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',
+ },
+};