mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-10-31 10:39:30 +00:00 
			
		
		
		
	Minor: Unit tests for observability and notification alert flow components (#14908)
This commit is contained in:
		
							parent
							
								
									ecfcdc89db
								
							
						
					
					
						commit
						3d7085e971
					
				| @ -387,17 +387,12 @@ const ObservabilityAlertsPage = withSuspenseFallback( | |||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const ObservabilityAlertDetailsPage = withSuspenseFallback( | const AlertDetailsPage = withSuspenseFallback( | ||||||
|   React.lazy( |   React.lazy(() => import('../../pages/AlertDetailsPage/AlertDetailsPage')) | ||||||
|     () => |  | ||||||
|       import( |  | ||||||
|         '../../pages/ObservabilityAlertDetailsPage/ObservabilityAlertDetailsPage' |  | ||||||
|       ) |  | ||||||
|   ) |  | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const NotificationsAlertDetailsPage = () => ( | const NotificationsAlertDetailsPage = () => ( | ||||||
|   <ObservabilityAlertDetailsPage isNotificationAlert /> |   <AlertDetailsPage isNotificationAlert /> | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const AddObservabilityPage = withSuspenseFallback( | const AddObservabilityPage = withSuspenseFallback( | ||||||
| @ -1070,7 +1065,7 @@ const AuthenticatedAppRouter: FunctionComponent = () => { | |||||||
| 
 | 
 | ||||||
|       <AdminProtectedRoute |       <AdminProtectedRoute | ||||||
|         exact |         exact | ||||||
|         component={ObservabilityAlertDetailsPage} |         component={AlertDetailsPage} | ||||||
|         path={ROUTES.OBSERVABILITY_ALERT_DETAILS} |         path={ROUTES.OBSERVABILITY_ALERT_DETAILS} | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,134 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { act, fireEvent, render, screen } from '@testing-library/react'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { MemoryRouter } from 'react-router-dom'; | ||||||
|  | import AddNotificationPage from './AddNotificationPage'; | ||||||
|  | 
 | ||||||
|  | const mockPush = jest.fn(); | ||||||
|  | const mockGoBack = jest.fn(); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../rest/alertsAPI', () => ({ | ||||||
|  |   getAlertsFromName: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       name: 'ActivityFeedAlert', | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  |   getResourceFunctions: jest.fn(), | ||||||
|  |   updateNotificationAlert: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       id: 'ActivityFeedAlert', | ||||||
|  |       data: [], | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  |   createNotificationAlert: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       alert: 'Notification', | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../utils/RouterUtils', () => ({ | ||||||
|  |   getNotificationAlertDetailsPath: jest.fn(), | ||||||
|  |   getSettingPath: jest.fn(), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../components/common/ResizablePanels/ResizablePanels', () => | ||||||
|  |   jest.fn().mockImplementation(({ firstPanel, secondPanel }) => ( | ||||||
|  |     <> | ||||||
|  |       <div>{firstPanel.children}</div> | ||||||
|  |       <div>{secondPanel.children}</div> | ||||||
|  |     </> | ||||||
|  |   )) | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | jest.mock('react-router-dom', () => ({ | ||||||
|  |   ...jest.requireActual('react-router-dom'), | ||||||
|  |   useHistory: jest.fn().mockImplementation(() => ({ | ||||||
|  |     push: mockPush, | ||||||
|  |     goBack: mockGoBack, | ||||||
|  |   })), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../hooks/useFqn', () => ({ | ||||||
|  |   useFqn: jest.fn().mockReturnValue({ fqn: '' }), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | describe('AddNotificationPage', () => { | ||||||
|  |   beforeEach(() => { | ||||||
|  |     jest.clearAllMocks(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should render Add Notification Page', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddNotificationPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect( | ||||||
|  |       await screen.findByText('label.notification-plural') | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should display the correct breadcrumb', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddNotificationPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     const breadcrumbLinks = screen.getAllByTestId('breadcrumb-link'); | ||||||
|  | 
 | ||||||
|  |     expect(breadcrumbLinks[0]).toHaveTextContent('label.setting-plural'); | ||||||
|  |     expect(breadcrumbLinks[1]).toHaveTextContent('label.notification-plural'); | ||||||
|  |     expect(breadcrumbLinks[2]).toHaveTextContent('label.create-entity'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should display SubTitle', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddNotificationPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect( | ||||||
|  |       await screen.findByText(/message.alerts-description/) | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should render Add alert button', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddNotificationPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(await screen.findByText(/label.create-entity/)).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should navigate back when the cancel button is clicked', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddNotificationPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const cancelButton = screen.getByTestId('cancel-button'); | ||||||
|  | 
 | ||||||
|  |     await act(async () => { | ||||||
|  |       fireEvent.click(cancelButton); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(mockGoBack).toHaveBeenCalled(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,150 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { act, fireEvent, render, screen } from '@testing-library/react'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { MemoryRouter } from 'react-router-dom'; | ||||||
|  | import AddObservabilityPage from './AddObservabilityPage'; | ||||||
|  | 
 | ||||||
|  | const MOCK_DATA = [ | ||||||
|  |   { | ||||||
|  |     id: '971a21b3-eeaf-4765-bda7-4e2cdb9788de', | ||||||
|  |     name: 'alert-test', | ||||||
|  |     fullyQualifiedName: 'alert-test', | ||||||
|  |     href: 'http://localhost:8585/api/v1/events/subscriptions/971a21b3-eeaf-4765-bda7-4e2cdb9788de', | ||||||
|  |     version: 0.1, | ||||||
|  |     updatedAt: 1682366749021, | ||||||
|  |     updatedBy: 'admin', | ||||||
|  |     filteringRules: { | ||||||
|  |       resources: ['all'], | ||||||
|  |       rules: [ | ||||||
|  |         { | ||||||
|  |           name: 'matchIngestionPipelineState', | ||||||
|  |           effect: 'include', | ||||||
|  |           condition: "matchIngestionPipelineState('partialSuccess')", | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |     subscriptionType: 'Email', | ||||||
|  |     subscriptionConfig: { | ||||||
|  |       receivers: ['test@gmail.com'], | ||||||
|  |     }, | ||||||
|  |     enabled: true, | ||||||
|  |     batchSize: 10, | ||||||
|  |     timeout: 10, | ||||||
|  |     readTimeout: 12, | ||||||
|  |     deleted: false, | ||||||
|  |     provider: 'user', | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  | const mockPush = jest.fn(); | ||||||
|  | const mockGoBack = jest.fn(); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../rest/observabilityAPI', () => ({ | ||||||
|  |   getObservabilityAlertByFQN: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       fqn: 'alert-test', | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  |   createObservabilityAlert: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       alert: 'Observability', | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  |   getResourceFunctions: jest.fn(), | ||||||
|  |   updateObservabilityAlert: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       id: 'test', | ||||||
|  |       jsonPatch: MOCK_DATA, | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../components/common/ResizablePanels/ResizablePanels', () => | ||||||
|  |   jest.fn().mockImplementation(({ firstPanel, secondPanel }) => ( | ||||||
|  |     <> | ||||||
|  |       <div>{firstPanel.children}</div> | ||||||
|  |       <div>{secondPanel.children}</div> | ||||||
|  |     </> | ||||||
|  |   )) | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | jest.mock('react-router-dom', () => ({ | ||||||
|  |   ...jest.requireActual('react-router-dom'), | ||||||
|  |   useHistory: jest.fn().mockImplementation(() => ({ | ||||||
|  |     push: mockPush, | ||||||
|  |     goBack: mockGoBack, | ||||||
|  |   })), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | describe('Add ObservabilityPage Alerts Page Tests', () => { | ||||||
|  |   it('should render Add Observability Page', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddObservabilityPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(await screen.findByText('label.observability')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should display SubTitle', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddObservabilityPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect( | ||||||
|  |       await screen.findByText(/message.alerts-description/) | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should render Add alert button', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddObservabilityPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(await screen.findByText(/label.create-entity/)).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should display the correct breadcrumb', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddObservabilityPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     const breadcrumbLinks = screen.getAllByTestId('breadcrumb-link'); | ||||||
|  | 
 | ||||||
|  |     expect(breadcrumbLinks[0]).toHaveTextContent('label.observability'); | ||||||
|  |     expect(breadcrumbLinks[1]).toHaveTextContent('label.alert-plural'); | ||||||
|  |     expect(breadcrumbLinks[2]).toHaveTextContent('label.create-entity'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should navigate back when the cancel button is clicked', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<AddObservabilityPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const cancelButton = screen.getByTestId('cancel-button'); | ||||||
|  | 
 | ||||||
|  |     await act(async () => { | ||||||
|  |       fireEvent.click(cancelButton); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(mockGoBack).toHaveBeenCalled(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,100 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { render, screen } from '@testing-library/react'; | ||||||
|  | import { Form, FormInstance } from 'antd'; | ||||||
|  | import React from 'react'; | ||||||
|  | import DestinationFormItem from './DestinationFormItem.component'; | ||||||
|  | 
 | ||||||
|  | jest.mock('../../../utils/Alerts/AlertsUtil', () => ({ | ||||||
|  |   getDestinationConfigField: jest | ||||||
|  |     .fn() | ||||||
|  |     .mockReturnValue(<div data-testid="destination-field" />), | ||||||
|  |   getSubscriptionTypeOptions: jest.fn().mockReturnValue([]), | ||||||
|  |   listLengthValidator: jest.fn().mockImplementation(() => Promise.resolve()), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('../../../utils/ObservabilityUtils', () => ({ | ||||||
|  |   checkIfDestinationIsInternal: jest.fn().mockImplementation(() => false), | ||||||
|  |   getAlertDestinationCategoryIcons: jest | ||||||
|  |     .fn() | ||||||
|  |     .mockImplementation(() => <span data-testid="icon">Icon</span>), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | const mockProps = { | ||||||
|  |   heading: 'heading', | ||||||
|  |   subHeading: 'subHeading', | ||||||
|  |   buttonLabel: 'buttonLabel', | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | describe('DestinationFormItem', () => { | ||||||
|  |   it('should renders without crashing', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render(<DestinationFormItem {...mockProps} />); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByText('heading')).toBeInTheDocument(); | ||||||
|  |     expect(screen.getByText('subHeading')).toBeInTheDocument(); | ||||||
|  |     expect(screen.getByText('buttonLabel')).toBeInTheDocument(); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('add-destination-button')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add destination button should be disabled if there is no selected trigger', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => []); | ||||||
|  | 
 | ||||||
|  |     render(<DestinationFormItem {...mockProps} />); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('add-destination-button')).toBeDisabled(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add destination button should be enabled if there is selected trigger', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render(<DestinationFormItem {...mockProps} />); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('add-destination-button')).toBeEnabled(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,109 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { render, screen } from '@testing-library/react'; | ||||||
|  | import { Form, FormInstance } from 'antd'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { EventFilterRule } from '../../../generated/events/eventSubscription'; | ||||||
|  | import { MOCK_FILTER_RESOURCES } from '../../../test/unit/mocks/observability.mock'; | ||||||
|  | import ObservabilityFormActionItem from './ObservabilityFormActionItem'; | ||||||
|  | 
 | ||||||
|  | jest.mock('../../../utils/Alerts/AlertsUtil', () => ({ | ||||||
|  |   getConditionalField: jest | ||||||
|  |     .fn() | ||||||
|  |     .mockReturnValue(<div data-testid="condition-field" />), | ||||||
|  |   getSupportedFilterOptions: jest.fn().mockReturnValue([]), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | const mockSupportedActions = MOCK_FILTER_RESOURCES.reduce( | ||||||
|  |   (resource, current) => { | ||||||
|  |     resource.push(...(current.supportedActions ?? [])); | ||||||
|  | 
 | ||||||
|  |     return resource; | ||||||
|  |   }, | ||||||
|  |   [] as EventFilterRule[] | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | describe('ObservabilityFormActionItem', () => { | ||||||
|  |   it('should renders without crashing', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormActionItem supportedActions={mockSupportedActions} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByText('label.action-plural')).toBeInTheDocument(); | ||||||
|  |     expect( | ||||||
|  |       screen.getByText('message.alerts-action-description') | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('actions-list')).toBeInTheDocument(); | ||||||
|  |     expect(screen.getByTestId('add-actions')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add actions button should be disabled if there is no selected trigger and filters', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => []); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormActionItem supportedActions={mockSupportedActions} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const addButton = screen.getByTestId('add-actions'); | ||||||
|  | 
 | ||||||
|  |     expect(addButton).toBeDisabled(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add actions button should not be disabled if there is selected trigger and filters', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormActionItem supportedActions={mockSupportedActions} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const addButton = screen.getByTestId('add-actions'); | ||||||
|  | 
 | ||||||
|  |     expect(addButton).not.toBeDisabled(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -67,7 +67,7 @@ function ObservabilityFormActionItem({ | |||||||
|                 fields.length < (supportedActions?.length ?? 1); |                 fields.length < (supportedActions?.length ?? 1); | ||||||
| 
 | 
 | ||||||
|               return ( |               return ( | ||||||
|                 <Row gutter={[16, 16]} key="actions"> |                 <Row data-testid="actions-list" gutter={[16, 16]} key="actions"> | ||||||
|                   {fields.map(({ key, name }) => { |                   {fields.map(({ key, name }) => { | ||||||
|                     const effect = |                     const effect = | ||||||
|                       form.getFieldValue([ |                       form.getFieldValue([ | ||||||
|  | |||||||
| @ -0,0 +1,109 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { render, screen } from '@testing-library/react'; | ||||||
|  | import { Form, FormInstance } from 'antd'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { EventFilterRule } from '../../../generated/events/eventSubscription'; | ||||||
|  | import { MOCK_FILTER_RESOURCES } from '../../../test/unit/mocks/observability.mock'; | ||||||
|  | import ObservabilityFormFiltersItem from './ObservabilityFormFiltersItem'; | ||||||
|  | 
 | ||||||
|  | jest.mock('../../../utils/Alerts/AlertsUtil', () => ({ | ||||||
|  |   getConditionalField: jest | ||||||
|  |     .fn() | ||||||
|  |     .mockReturnValue(<div data-testid="condition-field" />), | ||||||
|  |   getSupportedFilterOptions: jest.fn().mockReturnValue([]), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | const mockSupportedFilters = MOCK_FILTER_RESOURCES.reduce( | ||||||
|  |   (resource, current) => { | ||||||
|  |     resource.push(...(current.supportedFilters ?? [])); | ||||||
|  | 
 | ||||||
|  |     return resource; | ||||||
|  |   }, | ||||||
|  |   [] as EventFilterRule[] | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | describe('ObservabilityFormFiltersItem', () => { | ||||||
|  |   it('should renders without crashing', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormFiltersItem supportedFilters={mockSupportedFilters} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByText('label.filter-plural')).toBeInTheDocument(); | ||||||
|  |     expect( | ||||||
|  |       screen.getByText('message.alerts-filter-description') | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('filters-list')).toBeInTheDocument(); | ||||||
|  |     expect(screen.getByTestId('add-filters')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add filter button should be disabled if there is no selected trigger', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => []); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormFiltersItem supportedFilters={mockSupportedFilters} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const addButton = screen.getByTestId('add-filters'); | ||||||
|  | 
 | ||||||
|  |     expect(addButton).toBeDisabled(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('add filter button should not be disabled if there is selected trigger', () => { | ||||||
|  |     const setFieldValue = jest.fn(); | ||||||
|  |     const getFieldValue = jest.fn(); | ||||||
|  |     jest.spyOn(Form, 'useFormInstance').mockImplementation( | ||||||
|  |       () => | ||||||
|  |         ({ | ||||||
|  |           setFieldValue, | ||||||
|  |           getFieldValue, | ||||||
|  |         } as unknown as FormInstance) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const useWatchMock = jest.spyOn(Form, 'useWatch'); | ||||||
|  |     useWatchMock.mockImplementation(() => ['container']); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormFiltersItem supportedFilters={mockSupportedFilters} /> | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const addButton = screen.getByTestId('add-filters'); | ||||||
|  | 
 | ||||||
|  |     expect(addButton).not.toBeDisabled(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,81 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { render, screen } from '@testing-library/react'; | ||||||
|  | import userEvent from '@testing-library/user-event'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { act } from 'react-dom/test-utils'; | ||||||
|  | import { MemoryRouter } from 'react-router-dom'; | ||||||
|  | import { useFqn } from '../../../hooks/useFqn'; | ||||||
|  | import { MOCK_FILTER_RESOURCES } from '../../../test/unit/mocks/observability.mock'; | ||||||
|  | import ObservabilityFormTriggerItem from './ObservabilityFormTriggerItem'; | ||||||
|  | 
 | ||||||
|  | jest.mock('../../../hooks/useFqn', () => ({ | ||||||
|  |   useFqn: jest.fn().mockReturnValue({ fqn: '' }), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | jest.mock('antd', () => { | ||||||
|  |   const antd = jest.requireActual('antd'); | ||||||
|  | 
 | ||||||
|  |   return { | ||||||
|  |     ...antd, | ||||||
|  |     Form: { | ||||||
|  |       ...antd.Form, | ||||||
|  |       useFormInstance: jest.fn().mockImplementation(() => ({ | ||||||
|  |         setFieldValue: jest.fn(), | ||||||
|  |         getFieldValue: jest.fn(), | ||||||
|  |       })), | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('ObservabilityFormTriggerItem', () => { | ||||||
|  |   it('should renders without crashing', () => { | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormTriggerItem filterResources={MOCK_FILTER_RESOURCES} />, | ||||||
|  |       { wrapper: MemoryRouter } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByText('label.trigger')).toBeInTheDocument(); | ||||||
|  |     expect( | ||||||
|  |       screen.getByText('message.alerts-trigger-description') | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('add-trigger-button')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should render the trigger select when fqn is provided', () => { | ||||||
|  |     (useFqn as jest.Mock).mockImplementationOnce(() => ({ | ||||||
|  |       fqn: 'test', | ||||||
|  |     })); | ||||||
|  | 
 | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormTriggerItem filterResources={MOCK_FILTER_RESOURCES} />, | ||||||
|  |       { wrapper: MemoryRouter } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('trigger-select')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('should display select dropdown when clicked on add trigger button', async () => { | ||||||
|  |     render( | ||||||
|  |       <ObservabilityFormTriggerItem filterResources={MOCK_FILTER_RESOURCES} />, | ||||||
|  |       { wrapper: MemoryRouter } | ||||||
|  |     ); | ||||||
|  |     const addButton = screen.getByTestId('add-trigger-button'); | ||||||
|  |     await act(async () => { | ||||||
|  |       userEvent.click(addButton); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(screen.getByTestId('drop-down-menu')).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -11,6 +11,6 @@ | |||||||
|  *  limitations under the License. |  *  limitations under the License. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| export interface ObservabilityAlertDetailsPageProps { | export interface AlertDetailsPageProps { | ||||||
|   isNotificationAlert: boolean; |   isNotificationAlert: boolean; | ||||||
| } | } | ||||||
| @ -58,11 +58,11 @@ import { | |||||||
| } from '../../utils/RouterUtils'; | } from '../../utils/RouterUtils'; | ||||||
| import { getEntityIcon } from '../../utils/TableUtils'; | import { getEntityIcon } from '../../utils/TableUtils'; | ||||||
| import '../AddObservabilityPage/add-observability-page.less'; | import '../AddObservabilityPage/add-observability-page.less'; | ||||||
| import { ObservabilityAlertDetailsPageProps } from './ObservabilityAlertDetailsPage.interface'; | import { AlertDetailsPageProps } from './AlertDetailsPage.interface'; | ||||||
| 
 | 
 | ||||||
| function ObservabilityAlertDetailsPage({ | function AlertDetailsPage({ | ||||||
|   isNotificationAlert, |   isNotificationAlert = false, | ||||||
| }: Readonly<ObservabilityAlertDetailsPageProps>) { | }: Readonly<AlertDetailsPageProps>) { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   const { fqn } = useFqn(); |   const { fqn } = useFqn(); | ||||||
|   const history = useHistory(); |   const history = useHistory(); | ||||||
| @ -441,4 +441,4 @@ function ObservabilityAlertDetailsPage({ | |||||||
|   ); |   ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default ObservabilityAlertDetailsPage; | export default AlertDetailsPage; | ||||||
| @ -10,10 +10,11 @@ | |||||||
|  *  See the License for the specific language governing permissions and |  *  See the License for the specific language governing permissions and | ||||||
|  *  limitations under the License. |  *  limitations under the License. | ||||||
|  */ |  */ | ||||||
| import { render } from '@testing-library/react'; | import { act, render, screen } from '@testing-library/react'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import { MemoryRouter } from 'react-router-dom'; | import { MemoryRouter } from 'react-router-dom'; | ||||||
| import { ROUTES } from '../../constants/constants'; | import { ROUTES } from '../../constants/constants'; | ||||||
|  | import { getAllAlerts } from '../../rest/alertsAPI'; | ||||||
| import NotificationListPage from './NotificationListPage'; | import NotificationListPage from './NotificationListPage'; | ||||||
| 
 | 
 | ||||||
| const MOCK_DATA = [ | const MOCK_DATA = [ | ||||||
| @ -55,6 +56,12 @@ jest.mock('../../rest/alertsAPI', () => ({ | |||||||
|       paging: { total: 1 }, |       paging: { total: 1 }, | ||||||
|     }) |     }) | ||||||
|   ), |   ), | ||||||
|  |   getAlertsFromName: jest.fn().mockImplementation(() => | ||||||
|  |     Promise.resolve({ | ||||||
|  |       name: 'ActivityFeedAlert', | ||||||
|  |       params: 'all', | ||||||
|  |     }) | ||||||
|  |   ), | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| jest.mock('../../utils/GlobalSettingsUtils', () => ({ | jest.mock('../../utils/GlobalSettingsUtils', () => ({ | ||||||
| @ -77,28 +84,68 @@ jest.mock( | |||||||
|   } |   } | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| describe('Alerts Page Tests', () => { | describe('Notification Alerts Page Tests', () => { | ||||||
|   it('Title should be rendered', async () => { |   it('Title should be rendered', async () => { | ||||||
|     const { findByText } = render(<NotificationListPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<NotificationListPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText('label.notification-plural')).toBeInTheDocument(); |     expect( | ||||||
|  |       await screen.findByText('label.notification-plural') | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('SubTitle should be rendered', async () => { |   it('SubTitle should be rendered', async () => { | ||||||
|     const { findByText } = render(<NotificationListPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<NotificationListPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText(/message.alerts-description/)).toBeInTheDocument(); |     expect( | ||||||
|  |       await screen.findByText(/message.alerts-description/) | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('Add alert button should be rendered', async () => { |   it('Add alert button should be rendered', async () => { | ||||||
|     const { findByText } = render(<NotificationListPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<NotificationListPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText(/label.add-entity/)).toBeInTheDocument(); |     expect(await screen.findByText(/label.add-entity/)).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('Table should render alerts data', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<NotificationListPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const alertNameElement = await screen.findByTestId('alert-name'); | ||||||
|  | 
 | ||||||
|  |     expect(alertNameElement).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('Table should render no data', async () => { | ||||||
|  |     (getAllAlerts as jest.Mock).mockImplementation(() => | ||||||
|  |       Promise.resolve({ | ||||||
|  |         data: [], | ||||||
|  |         paging: { total: 1 }, | ||||||
|  |       }) | ||||||
|  |     ); | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<NotificationListPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const alertNameElement = await screen.findByText('label.no-entity'); | ||||||
|  | 
 | ||||||
|  |     expect(alertNameElement).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -10,9 +10,10 @@ | |||||||
|  *  See the License for the specific language governing permissions and |  *  See the License for the specific language governing permissions and | ||||||
|  *  limitations under the License. |  *  limitations under the License. | ||||||
|  */ |  */ | ||||||
| import { render } from '@testing-library/react'; | import { act, render, screen } from '@testing-library/react'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import { MemoryRouter } from 'react-router-dom'; | import { MemoryRouter } from 'react-router-dom'; | ||||||
|  | import { getAllAlerts } from '../../rest/alertsAPI'; | ||||||
| import ObservabilityAlertsPage from './ObservabilityAlertsPage'; | import ObservabilityAlertsPage from './ObservabilityAlertsPage'; | ||||||
| 
 | 
 | ||||||
| const MOCK_DATA = [ | const MOCK_DATA = [ | ||||||
| @ -55,29 +56,72 @@ jest.mock('../../rest/alertsAPI', () => ({ | |||||||
|     }) |     }) | ||||||
|   ), |   ), | ||||||
| })); | })); | ||||||
|  | jest.mock('../../components/PageLayoutV1/PageLayoutV1', () => { | ||||||
|  |   return jest.fn().mockImplementation(({ children }) => <div>{children}</div>); | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| describe.skip('Alerts Page Tests', () => { | describe('Observability Alerts Page Tests', () => { | ||||||
|   it('Title should be rendered', async () => { |   it('Title should be rendered', async () => { | ||||||
|     const { findByText } = render(<ObservabilityAlertsPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<ObservabilityAlertsPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText('label.alert-plural')).toBeInTheDocument(); |     expect(await screen.findByText('label.observability')).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('SubTitle should be rendered', async () => { |   it('SubTitle should be rendered', async () => { | ||||||
|     const { findByText } = render(<ObservabilityAlertsPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<ObservabilityAlertsPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText(/message.alerts-description/)).toBeInTheDocument(); |     expect( | ||||||
|  |       await screen.findByText(/message.alerts-description/) | ||||||
|  |     ).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('Add alert button should be rendered', async () => { |   it('Add alert button should be rendered', async () => { | ||||||
|     const { findByText } = render(<ObservabilityAlertsPage />, { |     await act(async () => { | ||||||
|       wrapper: MemoryRouter, |       render(<ObservabilityAlertsPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     expect(await findByText(/label.create-entity/)).toBeInTheDocument(); |     expect(await screen.findByText(/label.add-entity/)).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('Table should render alerts data', async () => { | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<ObservabilityAlertsPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const alertNameElement = await screen.findByText('alert-test'); | ||||||
|  | 
 | ||||||
|  |     expect(alertNameElement).toBeInTheDocument(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('Table should render no data', async () => { | ||||||
|  |     (getAllAlerts as jest.Mock).mockImplementation(() => | ||||||
|  |       Promise.resolve({ | ||||||
|  |         data: [], | ||||||
|  |         paging: { total: 1 }, | ||||||
|  |       }) | ||||||
|  |     ); | ||||||
|  |     await act(async () => { | ||||||
|  |       render(<ObservabilityAlertsPage />, { | ||||||
|  |         wrapper: MemoryRouter, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const alertNameElement = await screen.findByText( | ||||||
|  |       'message.adding-new-entity-is-easy-just-give-it-a-spin' | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(alertNameElement).toBeInTheDocument(); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -0,0 +1,343 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { FilterResourceDescriptor } from '../../../generated/events/filterResourceDescriptor'; | ||||||
|  | 
 | ||||||
|  | export const MOCK_FILTER_RESOURCES = [ | ||||||
|  |   { | ||||||
|  |     name: 'container', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Container Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event Filtering By Container Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetContainerSchemaChanges', | ||||||
|  |         displayName: 'Get Schema Changes', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetContainerSchemaChanges', | ||||||
|  |         description: 'Get Updates for Schema Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: "matchAnyFieldChange({'parent','children'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'pipeline', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Pipeline Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event Filtering By Pipeline Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetPipelineStatusUpdates', | ||||||
|  |         displayName: 'Get Pipeline Status Updates', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetPipelineStatusUpdates', | ||||||
|  |         description: 'Get Updates for Pipeline Status Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchIngestionPipelineState(${pipelineStateList})', | ||||||
|  |         arguments: ['pipelineStateList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'table', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Table Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event Filtering By Table Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetTableSchemaChanges', | ||||||
|  |         displayName: 'Get Schema Changes', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetTableSchemaChanges', | ||||||
|  |         description: 'Get Updates for Schema Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: "matchAnyFieldChange({'columns','dataModel','joins'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'GetTableMetricsUpdates', | ||||||
|  |         displayName: 'Get Table Metrics Updates', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetTableMetricsUpdates', | ||||||
|  |         description: 'Get Updates About Table Metrics', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: "matchAnyFieldChange({'customMetrics', 'profile'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'testCase', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Test Case Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event By Test Case Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByTableNameTestCaseBelongsTo', | ||||||
|  |         displayName: 'Table Name A Test Case Belongs To', | ||||||
|  |         fullyQualifiedName: | ||||||
|  |           'eventSubscription.filterByTableNameTestCaseBelongsTo', | ||||||
|  |         description: 'Event Filtering By Table Name A Test Case Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'filterByTableNameTestCaseBelongsTo(${tableNameList})', | ||||||
|  |         arguments: ['tableNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetTestCaseSchemaChanges', | ||||||
|  |         displayName: 'Get Schema Changes', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterBySchemaChange', | ||||||
|  |         description: 'Get Updates for Schema Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: | ||||||
|  |           "matchAnyFieldChange({'testDefinition','parameterValues','description'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'GetTestCaseStatusUpdates', | ||||||
|  |         displayName: 'Get Test Case Status Updates', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetTestCaseStatusUpdates', | ||||||
|  |         description: 'Get Status Updates Test Cases', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchTestResult(${testResultList})', | ||||||
|  |         arguments: ['testResultList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'testSuite', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Test Suite Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event Filtering By Test Suite Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetTestSuiteSchemaChanges', | ||||||
|  |         displayName: 'Get Schema Changes', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterBySchemaChange', | ||||||
|  |         description: 'Get Updates for Schema Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: | ||||||
|  |           "matchAnyFieldChange({'connection','pipelines','description'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'GetTestCaseStatusUpdatesUnderSuite', | ||||||
|  |         displayName: 'Get Test Case Status Updates belonging to a Test Suite', | ||||||
|  |         fullyQualifiedName: | ||||||
|  |           'eventSubscription.GetTestCaseStatusUpdatesUnderSuite', | ||||||
|  |         description: 'Get Status Updates Test Cases belonging to a Test Suite', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: | ||||||
|  |           'getTestCaseStatusIfInTestSuite(${testSuiteList}, ${testStatusList})', | ||||||
|  |         arguments: ['testSuiteList', 'testStatusList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'topic', | ||||||
|  |     supportedFilters: [ | ||||||
|  |       { | ||||||
|  |         name: 'filterByFqn', | ||||||
|  |         displayName: 'Topic Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByFqn', | ||||||
|  |         description: 'Event Filtering By Topic Name', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyEntityFqn(${fqnList})', | ||||||
|  |         arguments: ['fqnList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByDomain', | ||||||
|  |         displayName: 'Domain', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByDomain', | ||||||
|  |         description: 'Event Filtering By Domain a Entity Belongs To', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyDomain(${domainList})', | ||||||
|  |         arguments: ['domainList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'filterByOwner', | ||||||
|  |         displayName: 'Owner Name', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.filterByOwner', | ||||||
|  |         description: 'Event Filtering By Owner Name of Asset', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: 'matchAnyOwnerName(${ownerNameList})', | ||||||
|  |         arguments: ['ownerNameList'], | ||||||
|  |         inputType: 'runtime', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |     supportedActions: [ | ||||||
|  |       { | ||||||
|  |         name: 'GetTopicSchemaChanges', | ||||||
|  |         displayName: 'Get Schema Changes', | ||||||
|  |         fullyQualifiedName: 'eventSubscription.GetTopicSchemaChanges', | ||||||
|  |         description: 'Get Updates for Schema Changes', | ||||||
|  |         effect: 'include', | ||||||
|  |         condition: "matchAnyFieldChange({'messageSchema'})", | ||||||
|  |         arguments: [], | ||||||
|  |         inputType: 'none', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  | ] as FilterResourceDescriptor[]; | ||||||
| @ -10,8 +10,20 @@ | |||||||
|  *  See the License for the specific language governing permissions and |  *  See the License for the specific language governing permissions and | ||||||
|  *  limitations under the License. |  *  limitations under the License. | ||||||
|  */ |  */ | ||||||
| 
 | import React from 'react'; | ||||||
| import { getFunctionDisplayName } from './AlertsUtil'; | import { ReactComponent as AllActivityIcon } from '../../assets/svg/all-activity.svg'; | ||||||
|  | import { ReactComponent as MailIcon } from '../../assets/svg/ic-mail.svg'; | ||||||
|  | import { ReactComponent as MSTeamsIcon } from '../../assets/svg/ms-teams.svg'; | ||||||
|  | import { ReactComponent as SlackIcon } from '../../assets/svg/slack.svg'; | ||||||
|  | import { ReactComponent as WebhookIcon } from '../../assets/svg/webhook.svg'; | ||||||
|  | import { SubscriptionType } from '../../generated/events/eventSubscription'; | ||||||
|  | import { | ||||||
|  |   getAlertActionTypeDisplayName, | ||||||
|  |   getAlertsActionTypeIcon, | ||||||
|  |   getDisplayNameForEntities, | ||||||
|  |   getFunctionDisplayName, | ||||||
|  |   listLengthValidator, | ||||||
|  | } from './AlertsUtil'; | ||||||
| 
 | 
 | ||||||
| describe('AlertsUtil tests', () => { | describe('AlertsUtil tests', () => { | ||||||
|   it('getFunctionDisplayName should return correct text for matchAnyEntityFqn', () => { |   it('getFunctionDisplayName should return correct text for matchAnyEntityFqn', () => { | ||||||
| @ -47,4 +59,83 @@ describe('AlertsUtil tests', () => { | |||||||
|       'label.entity-id-match' |       'label.entity-id-match' | ||||||
|     ); |     ); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertsActionTypeIcon should return correct icon for Slack', () => { | ||||||
|  |     const icon = getAlertsActionTypeIcon(SubscriptionType.Slack); | ||||||
|  | 
 | ||||||
|  |     expect(icon).toStrictEqual(<SlackIcon height={16} width={16} />); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertsActionTypeIcon should return correct icon for Email', () => { | ||||||
|  |     const icon = getAlertsActionTypeIcon(SubscriptionType.Email); | ||||||
|  | 
 | ||||||
|  |     expect(icon).toStrictEqual(<MailIcon height={16} width={16} />); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertsActionTypeIcon should return correct icon for MSTeam', () => { | ||||||
|  |     const icon = getAlertsActionTypeIcon(SubscriptionType.MSTeams); | ||||||
|  | 
 | ||||||
|  |     expect(icon).toStrictEqual(<MSTeamsIcon height={16} width={16} />); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertsActionTypeIcon should return correct icon for ActivityFeed', () => { | ||||||
|  |     const icon = getAlertsActionTypeIcon(SubscriptionType.ActivityFeed); | ||||||
|  | 
 | ||||||
|  |     expect(icon).toStrictEqual(<AllActivityIcon height={16} width={16} />); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertsActionTypeIcon should return correct icon for generic', () => { | ||||||
|  |     const icon = getAlertsActionTypeIcon(SubscriptionType.Generic); | ||||||
|  | 
 | ||||||
|  |     expect(icon).toStrictEqual(<WebhookIcon height={16} width={16} />); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('listLengthValidator should return error function', async () => { | ||||||
|  |     const error = listLengthValidator('name', 64); | ||||||
|  | 
 | ||||||
|  |     expect(typeof error).toBe('function'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for Slack', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.Slack)).toBe( | ||||||
|  |       'label.slack' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for Email', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.Email)).toBe( | ||||||
|  |       'label.email' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for MSTeam', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.MSTeams)).toBe( | ||||||
|  |       'label.ms-team-plural' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for ActivityFeed', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.ActivityFeed)).toBe( | ||||||
|  |       'label.activity-feed-plural' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for generic', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.Generic)).toBe( | ||||||
|  |       'label.webhook' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getAlertActionTypeDisplayName should return correct text for GChat', () => { | ||||||
|  |     expect(getAlertActionTypeDisplayName(SubscriptionType.GChat)).toBe( | ||||||
|  |       'label.g-chat' | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('getDisplayNameForEntities should return correct text', () => { | ||||||
|  |     expect(getDisplayNameForEntities('kpi')).toBe('label.kpi-uppercase'); | ||||||
|  |     expect(getDisplayNameForEntities('mlmodel')).toBe('label.ml-model'); | ||||||
|  | 
 | ||||||
|  |     expect(getDisplayNameForEntities('unknown')).toBe('Unknown'); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
|  *  limitations under the License. |  *  limitations under the License. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import { Col, Input, Select, Switch, Tooltip, Typography } from 'antd'; | import { Col, Input, Select, Switch, Tooltip } from 'antd'; | ||||||
| import Form, { RuleObject } from 'antd/lib/form'; | import Form, { RuleObject } from 'antd/lib/form'; | ||||||
| import { AxiosError } from 'axios'; | import { AxiosError } from 'axios'; | ||||||
| import i18next, { t } from 'i18next'; | import i18next, { t } from 'i18next'; | ||||||
| @ -91,24 +91,6 @@ export const getFunctionDisplayName = (func: string): string => { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const StyledCard = ({ |  | ||||||
|   heading, |  | ||||||
|   subHeading, |  | ||||||
| }: { |  | ||||||
|   heading: string; |  | ||||||
|   subHeading: string; |  | ||||||
| }) => { |  | ||||||
|   return ( |  | ||||||
|     <div className="bg-grey p-sm rounded-4 min-h-24"> |  | ||||||
|       <Typography.Text>{heading}</Typography.Text> |  | ||||||
|       <br /> |  | ||||||
|       <Typography.Text className="text-xs text-grey-muted"> |  | ||||||
|         {subHeading} |  | ||||||
|       </Typography.Text> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
|  * @param name Field name used to identify which field has error |  * @param name Field name used to identify which field has error | ||||||
|  | |||||||
| @ -0,0 +1,90 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright 2024 Collate. | ||||||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  *  you may not use this file except in compliance with the License. | ||||||
|  |  *  You may obtain a copy of the License at | ||||||
|  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||||||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  *  See the License for the specific language governing permissions and | ||||||
|  |  *  limitations under the License. | ||||||
|  |  */ | ||||||
|  | import { SubscriptionCategory } from '../generated/events/eventSubscription'; | ||||||
|  | import { | ||||||
|  |   checkIfDestinationIsInternal, | ||||||
|  |   getAlertDestinationCategoryIcons, | ||||||
|  |   getConfigFieldFromDestinationType, | ||||||
|  | } from './ObservabilityUtils'; | ||||||
|  | 
 | ||||||
|  | describe('Observability Utils test', () => { | ||||||
|  |   describe('getAlertDestinationCategoryIcons', () => { | ||||||
|  |     it('should return the correct icon for each type', () => { | ||||||
|  |       const types = [ | ||||||
|  |         'Teams', | ||||||
|  |         'Users', | ||||||
|  |         'Admins', | ||||||
|  |         'GChat', | ||||||
|  |         'Slack', | ||||||
|  |         'Email', | ||||||
|  |         'MsTeams', | ||||||
|  |         'Followers', | ||||||
|  |         'Generic', | ||||||
|  |         'Owners', | ||||||
|  |       ]; | ||||||
|  |       types.forEach((type) => { | ||||||
|  |         const icon = getAlertDestinationCategoryIcons(type); | ||||||
|  | 
 | ||||||
|  |         expect(icon).not.toBeNull(); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should return null for an unknown type', () => { | ||||||
|  |       const icon = getAlertDestinationCategoryIcons('Unknown'); | ||||||
|  | 
 | ||||||
|  |       expect(icon).toBeNull(); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   describe('checkIfDestinationIsInternal', () => { | ||||||
|  |     it('should return true for internal destinations', () => { | ||||||
|  |       const destinationName = SubscriptionCategory.Admins; | ||||||
|  |       const result = checkIfDestinationIsInternal(destinationName); | ||||||
|  | 
 | ||||||
|  |       expect(result).toBe(true); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should return false for external destinations', () => { | ||||||
|  |       const destinationName = 'Test'; | ||||||
|  |       const result = checkIfDestinationIsInternal(destinationName); | ||||||
|  | 
 | ||||||
|  |       expect(result).toBe(false); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   describe('getConfigFieldFromDestinationType', () => { | ||||||
|  |     it('should return the correct config field for each type', () => { | ||||||
|  |       const types = [ | ||||||
|  |         SubscriptionCategory.Admins, | ||||||
|  |         SubscriptionCategory.Owners, | ||||||
|  |         SubscriptionCategory.Followers, | ||||||
|  |       ]; | ||||||
|  |       const expectedResults = [ | ||||||
|  |         'sendToAdmins', | ||||||
|  |         'sendToOwners', | ||||||
|  |         'sendToFollowers', | ||||||
|  |       ]; | ||||||
|  |       types.forEach((type, index) => { | ||||||
|  |         const result = getConfigFieldFromDestinationType(type); | ||||||
|  | 
 | ||||||
|  |         expect(result).toBe(expectedResults[index]); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should return an empty string for an unknown type', () => { | ||||||
|  |       const result = getConfigFieldFromDestinationType('Unknown'); | ||||||
|  | 
 | ||||||
|  |       expect(result).toBe(''); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aniket Katkar
						Aniket Katkar