From 16b94538dfdb36cd10d3b2321fef51adb3bcd77c Mon Sep 17 00:00:00 2001 From: Karan Hotchandani <33024356+karanh37@users.noreply.github.com> Date: Mon, 7 Jul 2025 21:06:51 +0530 Subject: [PATCH] fix stored procedure summary panel exception (#22189) --- .../utils/EntitySummaryPanelUtils.test.tsx | 108 ++++++++++++++++++ .../ui/src/utils/EntitySummaryPanelUtils.tsx | 2 +- .../mocks/EntitySummaryPanelUtils.mock.tsx | 88 ++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.test.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.test.tsx index bafd77fcb75..951bfac087b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.test.tsx @@ -11,9 +11,14 @@ * limitations under the License. */ +import { render, screen } from '@testing-library/react'; +import { isEmpty } from 'lodash'; +import { BrowserRouter } from 'react-router-dom'; +import { EntityType } from '../enums/entity.enum'; import { SummaryEntityType } from '../enums/EntitySummary.enum'; import { Column } from '../generated/entity/data/table'; import { + getEntityChildDetails, getFormattedEntityData, getHighlightOfListItem, getMapOfListHighlights, @@ -35,6 +40,9 @@ import { mockLinkBasedSummaryTitleDashboardResponse, mockLinkBasedSummaryTitleResponse, mockListItemNameHighlight, + mockStoredProcedureWithCode, + mockStoredProcedureWithEmptyCode, + mockStoredProcedureWithoutCode, mockTagFQNsForHighlight, mockTagsSortAndHighlightResponse, mockTextBasedSummaryTitleResponse, @@ -49,6 +57,16 @@ jest.mock('../constants/EntitySummaryPanelUtils.constant', () => ({ ], })); +jest.mock('../components/Database/SchemaEditor/SchemaEditor', () => { + return jest + .fn() + .mockImplementation(({ value }) => ( +
+ {isEmpty(value) ? 'No code available' : value} +
+ )); +}); + describe('EntitySummaryPanelUtils tests', () => { describe('getFormattedEntityData', () => { it('getFormattedEntityData should return formatted data properly for table columns data with nesting, and also sort the data based on highlights', () => { @@ -188,4 +206,94 @@ describe('EntitySummaryPanelUtils tests', () => { expect(result).toEqual(mockGetHighlightOfListItemResponse); }); }); + + describe('getEntityChildDetails', () => { + const renderWithRouter = (component: JSX.Element) => { + return render({component}); + }; + + describe('STORED_PROCEDURE cases', () => { + it('should render stored procedure with code correctly', () => { + const result = getEntityChildDetails( + EntityType.STORED_PROCEDURE, + mockStoredProcedureWithCode + ); + + renderWithRouter(result as JSX.Element); + + expect(screen.getByText('label.code')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toHaveTextContent( + 'CREATE PROCEDURE test_stored_procedure() BEGIN SELECT * FROM users; END' + ); + }); + + it('should render stored procedure without code correctly (null storedProcedureCode)', () => { + const result = getEntityChildDetails( + EntityType.STORED_PROCEDURE, + mockStoredProcedureWithoutCode + ); + + renderWithRouter(result as JSX.Element); + + expect(screen.getByText('label.code')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toHaveTextContent( + 'No code available' + ); + }); + + it('should render stored procedure with empty code correctly', () => { + const result = getEntityChildDetails( + EntityType.STORED_PROCEDURE, + mockStoredProcedureWithEmptyCode + ); + + renderWithRouter(result as JSX.Element); + + expect(screen.getByText('label.code')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toHaveTextContent( + 'No code available' + ); + }); + + it('should render stored procedure with undefined code field correctly', () => { + const mockStoredProcedureWithUndefinedCode = { + ...mockStoredProcedureWithCode, + storedProcedureCode: { + language: 'SQL', + code: undefined, + }, + }; + + const result = getEntityChildDetails( + EntityType.STORED_PROCEDURE, + mockStoredProcedureWithUndefinedCode + ); + + renderWithRouter(result as JSX.Element); + + expect(screen.getByText('label.code')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toBeInTheDocument(); + expect(screen.getByTestId('schema-editor')).toHaveTextContent( + 'No code available' + ); + }); + + it('should render stored procedure heading and testId correctly', () => { + const result = getEntityChildDetails( + EntityType.STORED_PROCEDURE, + mockStoredProcedureWithCode + ); + + renderWithRouter(result as JSX.Element); + + expect(screen.getByTestId('code-header')).toBeInTheDocument(); + expect(screen.getByTestId('code-header')).toHaveTextContent( + 'label.code' + ); + }); + }); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.tsx index cdff6b2e38d..f4a6054adc5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntitySummaryPanelUtils.tsx @@ -544,7 +544,7 @@ export const getEntityChildDetails = ( ( (entityInfo as StoredProcedure) .storedProcedureCode as StoredProcedureCodeObject - ).code ?? '' + )?.code ?? '' } /> ); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/mocks/EntitySummaryPanelUtils.mock.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/mocks/EntitySummaryPanelUtils.mock.tsx index 2ba372ae724..91fa7d4fd3c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/mocks/EntitySummaryPanelUtils.mock.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/mocks/EntitySummaryPanelUtils.mock.tsx @@ -17,6 +17,10 @@ import { Link } from 'react-router-dom'; import { BasicEntityInfo } from '../../components/Explore/EntitySummaryPanel/SummaryList/SummaryList.interface'; import { ICON_DIMENSION } from '../../constants/constants'; import { Task } from '../../generated/entity/data/pipeline'; +import { + StoredProcedure, + StoredProcedureCodeObject, +} from '../../generated/entity/data/storedProcedure'; import { Column, DataType, @@ -396,3 +400,87 @@ export const mockInvalidDataResponse = [ type: undefined, }, ]; + +export const mockStoredProcedureWithCode: StoredProcedure = { + id: '123e4567-e89b-12d3-a456-426614174000', + name: 'test_stored_procedure', + fullyQualifiedName: 'sample_database.test_stored_procedure', + description: 'A test stored procedure', + storedProcedureCode: { + language: 'SQL', + code: 'CREATE PROCEDURE test_stored_procedure()\nBEGIN\n SELECT * FROM users;\nEND', + } as StoredProcedureCodeObject, + databaseSchema: { + id: '456e7890-e12b-34c5-d678-901234567890', + name: 'test_schema', + fullyQualifiedName: 'sample_database.test_schema', + type: 'databaseSchema', + }, + database: { + id: '789e0123-e45f-67g8-h901-234567890123', + name: 'sample_database', + fullyQualifiedName: 'sample_database', + type: 'database', + }, + service: { + id: '012e3456-e78h-90i1-j234-567890123456', + name: 'mysql_service', + fullyQualifiedName: 'mysql_service', + type: 'databaseService', + }, +}; + +export const mockStoredProcedureWithoutCode: StoredProcedure = { + id: '123e4567-e89b-12d3-a456-426614174001', + name: 'test_stored_procedure_no_code', + fullyQualifiedName: 'sample_database.test_stored_procedure_no_code', + description: 'A test stored procedure without code', + storedProcedureCode: null, + databaseSchema: { + id: '456e7890-e12b-34c5-d678-901234567890', + name: 'test_schema', + fullyQualifiedName: 'sample_database.test_schema', + type: 'databaseSchema', + }, + database: { + id: '789e0123-e45f-67g8-h901-234567890123', + name: 'sample_database', + fullyQualifiedName: 'sample_database', + type: 'database', + }, + service: { + id: '012e3456-e78h-90i1-j234-567890123456', + name: 'mysql_service', + fullyQualifiedName: 'mysql_service', + type: 'databaseService', + }, +}; + +export const mockStoredProcedureWithEmptyCode: StoredProcedure = { + id: '123e4567-e89b-12d3-a456-426614174002', + name: 'test_stored_procedure_empty_code', + fullyQualifiedName: 'sample_database.test_stored_procedure_empty_code', + description: 'A test stored procedure with empty code', + storedProcedureCode: { + language: 'SQL', + code: '', + } as StoredProcedureCodeObject, + databaseSchema: { + id: '456e7890-e12b-34c5-d678-901234567890', + name: 'test_schema', + fullyQualifiedName: 'sample_database.test_schema', + type: 'databaseSchema', + }, + database: { + id: '789e0123-e45f-67g8-h901-234567890123', + name: 'sample_database', + fullyQualifiedName: 'sample_database', + type: 'database', + }, + service: { + id: '012e3456-e78h-90i1-j234-567890123456', + name: 'mysql_service', + fullyQualifiedName: 'mysql_service', + type: 'databaseService', + }, +};