diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreDiscovery.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreDiscovery.spec.ts index 271435faa77..f4829e13a08 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreDiscovery.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreDiscovery.spec.ts @@ -19,13 +19,16 @@ import { getJsonTreeObject } from '../../utils/exploreDiscovery'; test.use({ storageState: 'playwright/.auth/admin.json' }); const table = new TableClass(); +const table1 = new TableClass(); test.describe('Explore Assets Discovery', () => { test.beforeAll(async ({ browser }) => { const { apiContext, afterAction } = await createNewPage(browser); await table.create(apiContext); + await table1.create(apiContext); await table.delete(apiContext, false); + // await table1.delete(apiContext, false); await afterAction(); }); @@ -34,6 +37,7 @@ test.describe('Explore Assets Discovery', () => { const { apiContext, afterAction } = await createNewPage(browser); await table.delete(apiContext); + await table1.delete(apiContext); await afterAction(); }); @@ -183,4 +187,46 @@ test.describe('Explore Assets Discovery', () => { ) ).not.toBeAttached(); }); + + test('Should not display soft deleted assets in search suggestions', async ({ + page, + }) => { + await table1.visitEntityPage(page); + await page.waitForLoadState('networkidle'); + + await page.getByTestId('manage-button').click(); + await page.getByTestId('delete-button').click(); + + await expect( + page + .locator('.ant-modal-title') + .getByText( + `Delete table "${ + table1.entityResponseData.displayName ?? + table1.entityResponseData.name + }"` + ) + ).toBeVisible(); + + await page.getByTestId('confirmation-text-input').click(); + await page.getByTestId('confirmation-text-input').fill('DELETE'); + + await expect(page.getByTestId('confirm-button')).toBeEnabled(); + + await page.getByTestId('confirm-button').click(); + + await page.reload(); + + await expect(page.getByTestId('deleted-badge')).toBeVisible(); + + await redirectToHomePage(page); + await page.waitForLoadState('networkidle'); + + await page.getByTestId('searchBox').click(); + await page.getByTestId('searchBox').fill(table1.entityResponseData.name); + + expect( + page.locator('.ant-popover-inner-content').textContent() + ).not.toContain(table1.entityResponseData.name); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.test.tsx new file mode 100644 index 00000000000..a7293295a7a --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.test.tsx @@ -0,0 +1,171 @@ +/* + * Copyright 2025 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. + */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* + * Copyright 2022 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 { fireEvent, render, screen } from '@testing-library/react'; +import { useTranslation } from 'react-i18next'; +import { useTourProvider } from '../../context/TourProvider/TourProvider'; +import { SearchIndex } from '../../enums/search.enum'; +import { searchQuery } from '../../rest/searchAPI'; +import Suggestions from './Suggestions'; + +// Mock dependencies +jest.mock('../../rest/searchAPI'); +jest.mock('react-i18next', () => ({ + useTranslation: jest.fn(), +})); +jest.mock('../../context/TourProvider/TourProvider'); +jest.mock('../../utils/SearchUtils', () => ({ + filterOptionsByIndex: jest.fn((options, index) => { + return options.filter((option: any) => option._index === index); + }), + getGroupLabel: jest.fn((index) => `Group ${index}`), + getSuggestionElement: jest.fn((suggestion) => ( +