mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-14 18:27:35 +00:00
fix(ui) - glossary feedbacks (#11425)
* fix: show display name instead of name in left panel * fix: allow updating of empty owner in glossary and glossary term * feat: add jest tests * chore: add jest tests * fix: fix code smell * fix: review comments * chore: add jest test for term references modal --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
fc08683d3e
commit
95eff8c5e5
@ -83,13 +83,11 @@ const GlossaryDetailsRightPanel = ({
|
||||
};
|
||||
|
||||
const handleUpdatedOwner = (newOwner: Glossary['owner']) => {
|
||||
if (newOwner) {
|
||||
const updatedData = {
|
||||
...selectedData,
|
||||
owner: newOwner,
|
||||
};
|
||||
onUpdate(updatedData);
|
||||
}
|
||||
const updatedData = {
|
||||
...selectedData,
|
||||
owner: newOwner,
|
||||
};
|
||||
onUpdate(updatedData);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -100,23 +98,24 @@ const GlossaryDetailsRightPanel = ({
|
||||
<Typography.Text className="right-panel-label">
|
||||
{t('label.owner')}
|
||||
</Typography.Text>
|
||||
{(permissions.EditOwner || permissions.EditAll) && (
|
||||
<UserTeamSelectableList
|
||||
hasPermission={permissions.EditOwner || permissions.EditAll}
|
||||
owner={selectedData.owner}
|
||||
onUpdate={handleUpdatedOwner}>
|
||||
<Button
|
||||
className="cursor-pointer flex-center m-l-xss"
|
||||
data-testid="edit-owner-button"
|
||||
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
|
||||
size="small"
|
||||
type="text"
|
||||
/>
|
||||
</UserTeamSelectableList>
|
||||
)}
|
||||
{(permissions.EditOwner || permissions.EditAll) &&
|
||||
selectedData.owner && (
|
||||
<UserTeamSelectableList
|
||||
hasPermission={permissions.EditOwner || permissions.EditAll}
|
||||
owner={selectedData.owner}
|
||||
onUpdate={handleUpdatedOwner}>
|
||||
<Button
|
||||
className="cursor-pointer flex-center m-l-xss"
|
||||
data-testid="edit-owner-button"
|
||||
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
|
||||
size="small"
|
||||
type="text"
|
||||
/>
|
||||
</UserTeamSelectableList>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{selectedData.owner && getEntityName(selectedData.owner) ? (
|
||||
{selectedData.owner && getEntityName(selectedData.owner) && (
|
||||
<Space className="m-r-xss" size={4}>
|
||||
<ProfilePicture
|
||||
displayName={getEntityName(selectedData.owner)}
|
||||
@ -134,13 +133,27 @@ const GlossaryDetailsRightPanel = ({
|
||||
{getEntityName(selectedData.owner)}
|
||||
</Link>
|
||||
</Space>
|
||||
) : (
|
||||
<span className="text-grey-muted">
|
||||
{t('label.no-entity', {
|
||||
entity: t('label.owner-lowercase'),
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{!selectedData.owner &&
|
||||
(permissions.EditOwner || permissions.EditAll) && (
|
||||
<UserTeamSelectableList
|
||||
hasPermission={permissions.EditOwner || permissions.EditAll}
|
||||
owner={selectedData.owner}
|
||||
onUpdate={handleUpdatedOwner}>
|
||||
<TagButton
|
||||
className="tw-text-primary cursor-pointer"
|
||||
icon={<PlusIcon height={16} name="plus" width={16} />}
|
||||
label={t('label.add')}
|
||||
tooltip=""
|
||||
/>
|
||||
</UserTeamSelectableList>
|
||||
)}
|
||||
|
||||
{!selectedData.owner &&
|
||||
!(permissions.EditOwner || permissions.EditAll) && (
|
||||
<div>{NO_DATA_PLACEHOLDER}</div>
|
||||
)}
|
||||
</Col>
|
||||
<Col span="24">
|
||||
<div
|
||||
|
@ -60,6 +60,7 @@ const GlossaryTermReferencesModal = ({
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
data-testid="glossary-term-references-modal"
|
||||
footer={[
|
||||
<Button key="cancel-btn" type="link" onClick={onClose}>
|
||||
{t('label.cancel')}
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2023 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 GlossaryTermReferencesModal from './GlossaryTermReferencesModal.component';
|
||||
|
||||
const mockOnSave = jest.fn();
|
||||
const mockOnClose = jest.fn();
|
||||
|
||||
const references = [
|
||||
{ name: 'Reference 1', endpoint: 'http://example.com/1' },
|
||||
{ name: 'Reference 2', endpoint: 'http://example.com/2' },
|
||||
];
|
||||
|
||||
const defaultProps = {
|
||||
references,
|
||||
isVisible: true,
|
||||
onClose: mockOnClose,
|
||||
onSave: mockOnSave,
|
||||
};
|
||||
|
||||
describe('GlossaryTermReferencesModal', () => {
|
||||
it('renders correctly', () => {
|
||||
render(<GlossaryTermReferencesModal {...defaultProps} />);
|
||||
|
||||
expect(screen.getByText('label.reference-plural')).toBeInTheDocument();
|
||||
expect(screen.getByText('label.add')).toBeInTheDocument();
|
||||
expect(screen.getByText('label.cancel')).toBeInTheDocument();
|
||||
expect(screen.getByText('label.save')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('clicking Save button calls onSave with updated references', async () => {
|
||||
const { getAllByPlaceholderText, getByTestId } = render(
|
||||
<GlossaryTermReferencesModal {...{ ...defaultProps, references: [] }} />
|
||||
);
|
||||
|
||||
const nameInputs = getAllByPlaceholderText('label.name');
|
||||
const endpointInputs = getAllByPlaceholderText('label.endpoint');
|
||||
await act(async () => {
|
||||
fireEvent.click(getByTestId('save-btn'));
|
||||
|
||||
expect(mockOnSave).toHaveBeenCalledTimes(0);
|
||||
|
||||
fireEvent.change(nameInputs[0], { target: { value: 'google' } });
|
||||
fireEvent.change(endpointInputs[0], {
|
||||
target: { value: 'https://www.google.com' },
|
||||
});
|
||||
|
||||
fireEvent.click(getByTestId('save-btn'));
|
||||
});
|
||||
|
||||
expect(nameInputs[0]).toHaveValue('google');
|
||||
expect(endpointInputs[0]).toHaveValue('https://www.google.com');
|
||||
expect(getByTestId('save-btn')).toBeInTheDocument();
|
||||
|
||||
expect(mockOnSave).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSave.mock.calls).toEqual([
|
||||
[[{ name: 'google', endpoint: 'https://www.google.com' }]],
|
||||
]);
|
||||
});
|
||||
});
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2023 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, findByText, render, screen } from '@testing-library/react';
|
||||
import { MOCKED_GLOSSARY_TERMS, MOCK_PERMISSIONS } from 'mocks/Glossary.mock';
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import GlossaryOverviewTab from './GlossaryOverviewTab.component';
|
||||
|
||||
jest.mock('components/GlossaryTerms/tabs/GlossaryTermSynonyms', () => {
|
||||
return jest.fn().mockReturnValue(<p>GlossaryTermSynonyms</p>);
|
||||
});
|
||||
jest.mock('components/GlossaryTerms/tabs/RelatedTerms', () => {
|
||||
return jest.fn().mockReturnValue(<p>RelatedTerms</p>);
|
||||
});
|
||||
jest.mock('components/GlossaryTerms/tabs/GlossaryTermReferences', () => {
|
||||
return jest.fn().mockReturnValue(<p>GlossaryTermReferences</p>);
|
||||
});
|
||||
|
||||
jest.mock('components/common/description/DescriptionV1', () => {
|
||||
return jest.fn().mockReturnValue(<p>Description</p>);
|
||||
});
|
||||
|
||||
describe('GlossaryOverviewTab', () => {
|
||||
const onUpdate = jest.fn();
|
||||
const selectedData = MOCKED_GLOSSARY_TERMS[0];
|
||||
const permissions = MOCK_PERMISSIONS;
|
||||
const isGlossary = true;
|
||||
|
||||
beforeEach(() => {
|
||||
onUpdate.mockClear();
|
||||
});
|
||||
|
||||
it('renders the component', async () => {
|
||||
const { container } = render(
|
||||
<BrowserRouter>
|
||||
<GlossaryOverviewTab
|
||||
isGlossary={isGlossary}
|
||||
permissions={permissions}
|
||||
selectedData={selectedData}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
act(async () => {
|
||||
const description = await findByText(container, /Description/i);
|
||||
const synonymsContainer = await findByText(
|
||||
container,
|
||||
/GlossaryTermSynonyms/i
|
||||
);
|
||||
const relatedTermsContainer = await findByText(
|
||||
container,
|
||||
/RelatedTerms/i
|
||||
);
|
||||
const referencesContainer = await findByText(
|
||||
container,
|
||||
/GlossaryTermReferences/i
|
||||
);
|
||||
|
||||
expect(description).toBeInTheDocument();
|
||||
expect(synonymsContainer).toBeInTheDocument();
|
||||
expect(relatedTermsContainer).toBeInTheDocument();
|
||||
expect(referencesContainer).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('updated-by-container')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2023 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 { fireEvent, render } from '@testing-library/react';
|
||||
import { MOCKED_GLOSSARY_TERMS, MOCK_PERMISSIONS } from 'mocks/Glossary.mock';
|
||||
import React from 'react';
|
||||
import GlossaryTermReferences from './GlossaryTermReferences';
|
||||
|
||||
const mockOnGlossaryTermUpdate = jest.fn();
|
||||
|
||||
describe('GlossaryTermReferences', () => {
|
||||
it('renders glossary term references', async () => {
|
||||
const mockGlossaryTerm = MOCKED_GLOSSARY_TERMS[1];
|
||||
const mockPermissions = MOCK_PERMISSIONS;
|
||||
const { getByText, getByTestId } = render(
|
||||
<GlossaryTermReferences
|
||||
glossaryTerm={mockGlossaryTerm}
|
||||
permissions={mockPermissions}
|
||||
onGlossaryTermUpdate={mockOnGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
const sectionTitle = getByTestId('section-label.reference-plural');
|
||||
const editBtn = getByTestId('edit-button');
|
||||
|
||||
expect(sectionTitle).toBeInTheDocument();
|
||||
expect(sectionTitle).toHaveTextContent('label.reference-plural');
|
||||
|
||||
const reference = getByText('google');
|
||||
|
||||
expect(reference).toBeInTheDocument();
|
||||
expect(reference.closest('a')).toHaveAttribute(
|
||||
'href',
|
||||
'https://www.google.com'
|
||||
);
|
||||
expect(editBtn).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(editBtn);
|
||||
|
||||
expect(getByTestId('glossary-term-references-modal')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders add button', async () => {
|
||||
const mockGlossaryTerm = MOCKED_GLOSSARY_TERMS[0];
|
||||
const mockPermissions = MOCK_PERMISSIONS;
|
||||
const { getByTestId } = render(
|
||||
<GlossaryTermReferences
|
||||
glossaryTerm={mockGlossaryTerm}
|
||||
permissions={mockPermissions}
|
||||
onGlossaryTermUpdate={mockOnGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(getByTestId('term-references-add-button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render add button if no permission', async () => {
|
||||
const mockGlossaryTerm = MOCKED_GLOSSARY_TERMS[0];
|
||||
const mockPermissions = { ...MOCK_PERMISSIONS, EditAll: false };
|
||||
const { queryByTestId, findByText } = render(
|
||||
<GlossaryTermReferences
|
||||
glossaryTerm={mockGlossaryTerm}
|
||||
permissions={mockPermissions}
|
||||
onGlossaryTermUpdate={mockOnGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(queryByTestId('term-references-add-button')).toBeNull();
|
||||
|
||||
const noDataPlaceholder = await findByText(/--/i);
|
||||
|
||||
expect(noDataPlaceholder).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render edit button if no permission', async () => {
|
||||
const mockGlossaryTerm = MOCKED_GLOSSARY_TERMS[1];
|
||||
const mockPermissions = { ...MOCK_PERMISSIONS, EditAll: false };
|
||||
const { queryByTestId } = render(
|
||||
<GlossaryTermReferences
|
||||
glossaryTerm={mockGlossaryTerm}
|
||||
permissions={mockPermissions}
|
||||
onGlossaryTermUpdate={mockOnGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(queryByTestId('edit-button')).toBeNull();
|
||||
});
|
||||
});
|
@ -137,6 +137,7 @@ const GlossaryTermReferences = ({
|
||||
{permissions.EditAll && references.length === 0 && (
|
||||
<TagButton
|
||||
className="tw-text-primary cursor-pointer"
|
||||
dataTestId="term-references-add-button"
|
||||
icon={<PlusIcon height={16} name="plus" width={16} />}
|
||||
label={t('label.add')}
|
||||
tooltip=""
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2023 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 } from '@testing-library/react';
|
||||
import { MOCKED_GLOSSARY_TERMS, MOCK_PERMISSIONS } from 'mocks/Glossary.mock';
|
||||
import React from 'react';
|
||||
import GlossaryTermSynonyms from './GlossaryTermSynonyms';
|
||||
|
||||
const onGlossaryTermUpdate = jest.fn();
|
||||
|
||||
describe('GlossaryTermSynonyms', () => {
|
||||
it('renders synonyms and edit button', () => {
|
||||
const glossaryTerm = MOCKED_GLOSSARY_TERMS[1];
|
||||
const permissions = MOCK_PERMISSIONS;
|
||||
const { getByTestId, getByText } = render(
|
||||
<GlossaryTermSynonyms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
const synonymsContainer = getByTestId('synonyms-container');
|
||||
const synonymItem = getByText('accessory');
|
||||
const editBtn = getByTestId('edit-button');
|
||||
|
||||
expect(synonymsContainer).toBeInTheDocument();
|
||||
expect(synonymItem).toBeInTheDocument();
|
||||
expect(editBtn).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders add button', () => {
|
||||
const glossaryTerm = MOCKED_GLOSSARY_TERMS[0];
|
||||
const permissions = MOCK_PERMISSIONS;
|
||||
const { getByTestId } = render(
|
||||
<GlossaryTermSynonyms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
const synonymsContainer = getByTestId('synonyms-container');
|
||||
const synonymAddBtn = getByTestId('synonym-add-button');
|
||||
|
||||
expect(synonymsContainer).toBeInTheDocument();
|
||||
expect(synonymAddBtn).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render add button if no permission', async () => {
|
||||
const glossaryTerm = MOCKED_GLOSSARY_TERMS[0];
|
||||
const permissions = { ...MOCK_PERMISSIONS, EditAll: false };
|
||||
const { getByTestId, queryByTestId, findByText } = render(
|
||||
<GlossaryTermSynonyms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
const synonymsContainer = getByTestId('synonyms-container');
|
||||
const synonymAddBtn = queryByTestId('synonym-add-button');
|
||||
|
||||
expect(synonymsContainer).toBeInTheDocument();
|
||||
expect(synonymAddBtn).toBeNull();
|
||||
|
||||
const noDataPlaceholder = await findByText(/--/i);
|
||||
|
||||
expect(noDataPlaceholder).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render edit button if no permission', () => {
|
||||
const glossaryTerm = MOCKED_GLOSSARY_TERMS[1];
|
||||
const permissions = { ...MOCK_PERMISSIONS, EditAll: false };
|
||||
const { getByTestId, queryByTestId } = render(
|
||||
<GlossaryTermSynonyms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
const synonymsContainer = getByTestId('synonyms-container');
|
||||
const editBtn = queryByTestId('edit-button');
|
||||
|
||||
expect(synonymsContainer).toBeInTheDocument();
|
||||
expect(editBtn).toBeNull();
|
||||
});
|
||||
});
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2023 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 } from '@testing-library/react';
|
||||
import { MOCKED_GLOSSARY_TERMS, MOCK_PERMISSIONS } from 'mocks/Glossary.mock';
|
||||
import React from 'react';
|
||||
import RelatedTerms from './RelatedTerms';
|
||||
|
||||
const glossaryTerm = MOCKED_GLOSSARY_TERMS[2];
|
||||
|
||||
const permissions = MOCK_PERMISSIONS;
|
||||
|
||||
const onGlossaryTermUpdate = jest.fn();
|
||||
|
||||
describe('RelatedTerms', () => {
|
||||
it('should render the component', () => {
|
||||
const { container } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the related terms', () => {
|
||||
const { getByText } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(getByText('Business Customer')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the add button if there are no related terms and the user has edit permissions', () => {
|
||||
const { getByTestId } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={{ ...glossaryTerm, relatedTerms: [] }}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(getByTestId('related-term-add-button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show the add button if there are no related terms and the user does not have edit permissions', async () => {
|
||||
const { queryByTestId, findByText } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={{ ...glossaryTerm, relatedTerms: [] }}
|
||||
permissions={{ ...MOCK_PERMISSIONS, EditAll: false }}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(queryByTestId('related-term-add-button')).toBeNull();
|
||||
|
||||
const noDataPlaceholder = await findByText(/--/i);
|
||||
|
||||
expect(noDataPlaceholder).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the edit button if there are related terms and the user has edit permissions', () => {
|
||||
const { getByTestId } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={glossaryTerm}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(getByTestId('edit-button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show the edit button if there are no related terms and the user has edit permissions', () => {
|
||||
const { queryByTestId } = render(
|
||||
<RelatedTerms
|
||||
glossaryTerm={{ ...glossaryTerm, relatedTerms: [] }}
|
||||
permissions={permissions}
|
||||
onGlossaryTermUpdate={onGlossaryTermUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(queryByTestId('edit-button')).toBeNull();
|
||||
});
|
||||
});
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
import { OperationPermission } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||
import { Status } from '../generated/entity/data/glossaryTerm';
|
||||
import { ProviderType, Status } from '../generated/entity/data/glossaryTerm';
|
||||
|
||||
export const mockedAssetData = {
|
||||
currPage: 1,
|
||||
@ -429,3 +429,290 @@ export const MOCK_PERMISSIONS = {
|
||||
ViewTests: true,
|
||||
ViewUsage: true,
|
||||
} as OperationPermission;
|
||||
|
||||
export const MOCKED_GLOSSARY_TERMS = [
|
||||
{
|
||||
id: 'a735e9c0-a98f-43aa-8c15-490a55198f3c',
|
||||
name: 'Air Conditioners',
|
||||
displayName: 'Air Conditioners',
|
||||
description: 'Air Conditioners',
|
||||
fullyQualifiedName: 'Electronics.Air Conditioners',
|
||||
synonyms: [],
|
||||
glossary: {
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
type: 'glossary',
|
||||
name: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
deleted: false,
|
||||
},
|
||||
children: [],
|
||||
relatedTerms: [],
|
||||
references: [],
|
||||
version: 0.1,
|
||||
updatedAt: 1682348752125,
|
||||
updatedBy: 'karan',
|
||||
reviewers: [],
|
||||
owner: {
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
type: 'user',
|
||||
name: 'karan',
|
||||
fullyQualifiedName: 'karan',
|
||||
displayName: 'Karan Hotchandani',
|
||||
deleted: false,
|
||||
},
|
||||
tags: [],
|
||||
status: Status.Draft,
|
||||
deleted: false,
|
||||
provider: ProviderType.User,
|
||||
mutuallyExclusive: false,
|
||||
},
|
||||
{
|
||||
id: '18f310c6-7f43-4b4e-9d8c-5d30ff913a3c',
|
||||
name: 'Mobiles',
|
||||
displayName: 'Mobiles',
|
||||
description: 'Mobiles description',
|
||||
fullyQualifiedName: 'Electronics.Mobiles',
|
||||
synonyms: ['accessory'],
|
||||
glossary: {
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
type: 'glossary',
|
||||
name: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
deleted: false,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
id: 'b54bf954-a4bf-4566-9213-3130c9ec27ea',
|
||||
type: 'glossaryTerm',
|
||||
name: 'Iphones',
|
||||
fullyQualifiedName: 'Electronics.Mobiles.Iphones',
|
||||
description: 'Updated description',
|
||||
displayName: 'Iphones',
|
||||
deleted: false,
|
||||
},
|
||||
],
|
||||
relatedTerms: [],
|
||||
references: [
|
||||
{
|
||||
name: 'google',
|
||||
endpoint: 'https://www.google.com',
|
||||
},
|
||||
],
|
||||
version: 0.1,
|
||||
updatedAt: 1682348731309,
|
||||
updatedBy: 'karan',
|
||||
reviewers: [],
|
||||
owner: {
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
type: 'user',
|
||||
name: 'karan',
|
||||
fullyQualifiedName: 'karan',
|
||||
displayName: 'Karan Hotchandani',
|
||||
deleted: false,
|
||||
},
|
||||
tags: [],
|
||||
status: Status.Draft,
|
||||
deleted: false,
|
||||
provider: ProviderType.User,
|
||||
mutuallyExclusive: false,
|
||||
},
|
||||
{
|
||||
id: 'b54bf954-a4bf-4566-9213-3130c9ec27ea',
|
||||
name: 'Iphones',
|
||||
displayName: 'Iphones',
|
||||
description: 'Updated description',
|
||||
fullyQualifiedName: 'Electronics.Mobiles.Iphones',
|
||||
synonyms: ['accessory'],
|
||||
glossary: {
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
type: 'glossary',
|
||||
name: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
deleted: false,
|
||||
},
|
||||
parent: {
|
||||
id: '18f310c6-7f43-4b4e-9d8c-5d30ff913a3c',
|
||||
type: 'glossaryTerm',
|
||||
name: 'Mobiles',
|
||||
fullyQualifiedName: 'Electronics.Mobiles',
|
||||
description: 'Mobiles description',
|
||||
displayName: 'Mobiles',
|
||||
deleted: false,
|
||||
},
|
||||
children: [],
|
||||
relatedTerms: [
|
||||
{
|
||||
id: '2a5a09ac-1c9a-42b8-bdf2-4adb4f141f55',
|
||||
type: 'glossaryTerm',
|
||||
name: 'Business Customer',
|
||||
fullyQualifiedName: 'Customer.Business Customer',
|
||||
description: 'Business Customer',
|
||||
displayName: 'Business Customer',
|
||||
deleted: false,
|
||||
},
|
||||
],
|
||||
references: [
|
||||
{
|
||||
name: 'google',
|
||||
endpoint: 'https://www.google.com',
|
||||
},
|
||||
],
|
||||
version: 0.4,
|
||||
updatedAt: 1682348835466,
|
||||
updatedBy: 'karan',
|
||||
reviewers: [],
|
||||
owner: {
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
type: 'user',
|
||||
name: 'karan',
|
||||
fullyQualifiedName: 'karan',
|
||||
displayName: 'Karan Hotchandani',
|
||||
deleted: false,
|
||||
},
|
||||
tags: [],
|
||||
status: Status.Draft,
|
||||
deleted: false,
|
||||
provider: ProviderType.User,
|
||||
mutuallyExclusive: false,
|
||||
},
|
||||
];
|
||||
|
||||
export const MOCKED_GLOSSARY_TERMS_TREE = [
|
||||
{
|
||||
children: undefined,
|
||||
deleted: false,
|
||||
description: 'Air Conditioners',
|
||||
displayName: 'Air Conditioners',
|
||||
fullyQualifiedName: 'Electronics.Air Conditioners',
|
||||
glossary: {
|
||||
deleted: false,
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
name: 'Electronics',
|
||||
type: 'glossary',
|
||||
},
|
||||
id: 'a735e9c0-a98f-43aa-8c15-490a55198f3c',
|
||||
mutuallyExclusive: false,
|
||||
name: 'Air Conditioners',
|
||||
owner: {
|
||||
deleted: false,
|
||||
displayName: 'Karan Hotchandani',
|
||||
fullyQualifiedName: 'karan',
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
name: 'karan',
|
||||
type: 'user',
|
||||
},
|
||||
provider: 'user',
|
||||
references: [],
|
||||
relatedTerms: [],
|
||||
reviewers: [],
|
||||
status: 'Draft',
|
||||
synonyms: [],
|
||||
tags: [],
|
||||
updatedAt: 1682348752125,
|
||||
updatedBy: 'karan',
|
||||
version: 0.1,
|
||||
},
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: undefined,
|
||||
deleted: false,
|
||||
description: 'Updated description',
|
||||
displayName: 'Iphones',
|
||||
fullyQualifiedName: 'Electronics.Mobiles.Iphones',
|
||||
glossary: {
|
||||
deleted: false,
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
name: 'Electronics',
|
||||
type: 'glossary',
|
||||
},
|
||||
id: 'b54bf954-a4bf-4566-9213-3130c9ec27ea',
|
||||
mutuallyExclusive: false,
|
||||
name: 'Iphones',
|
||||
owner: {
|
||||
deleted: false,
|
||||
displayName: 'Karan Hotchandani',
|
||||
fullyQualifiedName: 'karan',
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
name: 'karan',
|
||||
type: 'user',
|
||||
},
|
||||
parent: {
|
||||
deleted: false,
|
||||
description: 'Mobiles description',
|
||||
displayName: 'Mobiles',
|
||||
fullyQualifiedName: 'Electronics.Mobiles',
|
||||
id: '18f310c6-7f43-4b4e-9d8c-5d30ff913a3c',
|
||||
name: 'Mobiles',
|
||||
type: 'glossaryTerm',
|
||||
},
|
||||
provider: 'user',
|
||||
references: [{ endpoint: 'https://www.google.com', name: 'google' }],
|
||||
relatedTerms: [
|
||||
{
|
||||
deleted: false,
|
||||
description: 'Business Customer',
|
||||
displayName: 'Business Customer',
|
||||
fullyQualifiedName: 'Customer.Business Customer',
|
||||
id: '2a5a09ac-1c9a-42b8-bdf2-4adb4f141f55',
|
||||
name: 'Business Customer',
|
||||
type: 'glossaryTerm',
|
||||
},
|
||||
],
|
||||
reviewers: [],
|
||||
status: 'Draft',
|
||||
synonyms: ['accessory'],
|
||||
tags: [],
|
||||
updatedAt: 1682348835466,
|
||||
updatedBy: 'karan',
|
||||
version: 0.4,
|
||||
},
|
||||
],
|
||||
deleted: false,
|
||||
description: 'Mobiles description',
|
||||
displayName: 'Mobiles',
|
||||
fullyQualifiedName: 'Electronics.Mobiles',
|
||||
glossary: {
|
||||
deleted: false,
|
||||
description: 'Electronics description',
|
||||
displayName: 'Electronics',
|
||||
fullyQualifiedName: 'Electronics',
|
||||
id: '3aaaa48f-a153-483d-9031-12d9f2426cfb',
|
||||
name: 'Electronics',
|
||||
type: 'glossary',
|
||||
},
|
||||
id: '18f310c6-7f43-4b4e-9d8c-5d30ff913a3c',
|
||||
mutuallyExclusive: false,
|
||||
name: 'Mobiles',
|
||||
owner: {
|
||||
deleted: false,
|
||||
displayName: 'Karan Hotchandani',
|
||||
fullyQualifiedName: 'karan',
|
||||
id: '93bb9db6-ead6-40d8-a32a-1c6bd6b2c143',
|
||||
name: 'karan',
|
||||
type: 'user',
|
||||
},
|
||||
provider: 'user',
|
||||
references: [{ endpoint: 'https://www.google.com', name: 'google' }],
|
||||
relatedTerms: [],
|
||||
reviewers: [],
|
||||
status: 'Draft',
|
||||
synonyms: ['accessory'],
|
||||
tags: [],
|
||||
updatedAt: 1682348731309,
|
||||
updatedBy: 'karan',
|
||||
version: 0.1,
|
||||
},
|
||||
];
|
||||
|
@ -25,6 +25,7 @@ import { Operation } from 'generated/entity/policies/policy';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { getEntityName } from 'utils/EntityUtils';
|
||||
import { checkPermission } from 'utils/PermissionsUtils';
|
||||
import { getGlossaryPath } from 'utils/RouterUtils';
|
||||
import { GlossaryLeftPanelProps } from './GlossaryLeftPanel.interface';
|
||||
@ -54,7 +55,7 @@ const GlossaryLeftPanel = ({ glossaries }: GlossaryLeftPanelProps) => {
|
||||
...acc,
|
||||
{
|
||||
key: glossary.name,
|
||||
label: glossary.name,
|
||||
label: getEntityName(glossary),
|
||||
icon: <IconFolder height={16} width={16} />,
|
||||
},
|
||||
];
|
||||
|
@ -87,7 +87,7 @@ describe('Test GlossaryLeftPanel component', () => {
|
||||
).toBeInTheDocument();
|
||||
expect(await screen.findByText('label.glossary')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(mockedGlossaries[0].name)
|
||||
await screen.findByText(mockedGlossaries[0].displayName)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@ -112,7 +112,7 @@ describe('Test GlossaryLeftPanel component', () => {
|
||||
render(<GlossaryLeftPanel glossaries={mockedGlossaries} />);
|
||||
});
|
||||
|
||||
const menuItem = await screen.findByText(mockedGlossaries[0].name);
|
||||
const menuItem = await screen.findByText(mockedGlossaries[0].displayName);
|
||||
|
||||
expect(menuItem).toBeInTheDocument();
|
||||
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2023 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 {
|
||||
MOCKED_GLOSSARY_TERMS,
|
||||
MOCKED_GLOSSARY_TERMS_TREE,
|
||||
} from 'mocks/Glossary.mock';
|
||||
import {
|
||||
buildTree,
|
||||
formatRelatedTermOptions,
|
||||
getQueryFilterToExcludeTerm,
|
||||
} from './GlossaryUtils';
|
||||
|
||||
describe('Glossary Utils', () => {
|
||||
it('getQueryFilterToExcludeTerm returns the correct query filter', () => {
|
||||
const fqn = 'example';
|
||||
const expectedQueryFilter = {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
bool: {
|
||||
must_not: {
|
||||
term: {
|
||||
'tags.tagFQN': fqn,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const queryFilter = getQueryFilterToExcludeTerm(fqn);
|
||||
|
||||
expect(queryFilter).toEqual(expectedQueryFilter);
|
||||
});
|
||||
|
||||
it('should build the tree correctly', () => {
|
||||
expect(buildTree(MOCKED_GLOSSARY_TERMS)).toEqual(
|
||||
MOCKED_GLOSSARY_TERMS_TREE
|
||||
);
|
||||
});
|
||||
|
||||
it('formatRelatedTermOptions - should format related term options correctly', () => {
|
||||
const data = [
|
||||
{ id: 'term1', displayName: 'Term One', type: 'glossaryTerm' },
|
||||
{ id: 'term2', name: 'Term Two', type: 'glossaryTerm' },
|
||||
];
|
||||
const expectedOutput = [
|
||||
{
|
||||
id: 'term1',
|
||||
value: 'term1',
|
||||
label: 'Term One',
|
||||
key: 'term1',
|
||||
displayName: 'Term One',
|
||||
type: 'glossaryTerm',
|
||||
},
|
||||
{
|
||||
id: 'term2',
|
||||
value: 'term2',
|
||||
label: 'Term Two',
|
||||
name: 'Term Two',
|
||||
key: 'term2',
|
||||
type: 'glossaryTerm',
|
||||
},
|
||||
];
|
||||
|
||||
expect(formatRelatedTermOptions(data)).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it('formatRelatedTermOptions -should return an empty array if no data is provided', () => {
|
||||
expect(formatRelatedTermOptions(undefined)).toEqual([]);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user