Browse Source

SONAR-22102 Fixing missing udpate of project tags update (#11002)

copy_of_master
Mathieu Suen 2 weeks ago
parent
commit
3a0102ec7c

+ 13
- 5
server/sonar-web/src/main/js/apps/projectInformation/about/components/MetaTags.tsx View File

@@ -17,9 +17,10 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Spinner } from '@sonarsource/echoes-react';
import { MultiSelector, SubHeading, Tags } from 'design-system';
import { difference, without } from 'lodash';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { searchProjectTags, setApplicationTags, setProjectTags } from '../../../../api/components';
import Tooltip from '../../../../components/controls/Tooltip';
import { PopupPlacement } from '../../../../components/ui/popups';
@@ -33,7 +34,11 @@ interface Props {
}

export default function MetaTags(props: Props) {
const [open, setOpen] = React.useState(false);
const [loading, setLoading] = useState(false);

useEffect(() => {
setLoading(false);
}, [props.component.tags]);

const canUpdateTags = () => {
const { configuration } = props.component;
@@ -57,6 +62,7 @@ export default function MetaTags(props: Props) {
};

const handleSetProjectTags = (values: string[]) => {
setLoading(true);
setTags(values).then(
() => props.onComponentChange({ tags: values }),
() => {},
@@ -73,13 +79,15 @@ export default function MetaTags(props: Props) {
ariaTagsListLabel={translate('tags')}
className="project-info-tags"
emptyText={translate('no_tags')}
overlay={<MetaTagsSelector selectedTags={tags} setProjectTags={handleSetProjectTags} />}
overlay={
<Spinner isLoading={loading}>
<MetaTagsSelector selectedTags={tags} setProjectTags={handleSetProjectTags} />
</Spinner>
}
popupPlacement={PopupPlacement.Bottom}
tags={tags}
tagsToDisplay={2}
tooltip={Tooltip}
open={open}
onClose={() => setOpen(false)}
/>
</>
);

+ 29
- 23
server/sonar-web/src/main/js/apps/projectInformation/about/components/__tests__/MetaTags-test.tsx View File

@@ -24,6 +24,7 @@ import { setApplicationTags, setProjectTags } from '../../../../../api/component
import { mockComponent } from '../../../../../helpers/mocks/component';
import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
import { ComponentQualifier } from '../../../../../types/component';
import { Component } from '../../../../../types/types';
import MetaTags from '../MetaTags';

jest.mock('../../../../../api/components', () => ({
@@ -45,8 +46,6 @@ it('should render without tags and admin rights', async () => {

it('should allow to edit tags for a project', async () => {
const user = userEvent.setup();

const onComponentChange = jest.fn();
const component = mockComponent({
key: 'my-second-project',
tags: ['foo', 'bar'],
@@ -56,7 +55,7 @@ it('should allow to edit tags for a project', async () => {
name: 'MySecondProject',
});

renderMetaTags({ component, onComponentChange });
renderMetaTags(component);

expect(await screen.findByText('foo, bar')).toBeInTheDocument();
expect(screen.getByRole('button')).toBeInTheDocument();
@@ -66,15 +65,11 @@ it('should allow to edit tags for a project', async () => {
expect(await screen.findByRole('checkbox', { name: 'best' })).toBeInTheDocument();

await user.click(screen.getByRole('checkbox', { name: 'best' }));
expect(onComponentChange).toHaveBeenCalledWith({ tags: ['foo', 'bar', 'best'] });

onComponentChange.mockClear();
expect(await screen.findByRole('button', { name: 'foo bar ... +' })).toBeInTheDocument();

/*
* Since we're not actually updating the tags, we're back to having the foo, bar only
*/
await user.click(screen.getByRole('checkbox', { name: 'bar' }));
expect(onComponentChange).toHaveBeenCalledWith({ tags: ['foo'] });

expect(await screen.findByRole('button', { name: 'foo best +' })).toBeInTheDocument();

expect(setProjectTags).toHaveBeenCalled();
expect(setApplicationTags).not.toHaveBeenCalled();
@@ -85,14 +80,14 @@ it('should allow to edit tags for a project', async () => {
it('should set tags for an app', async () => {
const user = userEvent.setup();

renderMetaTags({
component: mockComponent({
renderMetaTags(
mockComponent({
configuration: {
showSettings: true,
},
qualifier: ComponentQualifier.Application,
}),
});
);

await user.click(screen.getByRole('button', { name: 'no_tags +' }));

@@ -102,14 +97,25 @@ it('should set tags for an app', async () => {
expect(setApplicationTags).toHaveBeenCalled();
});

function renderMetaTags(overrides: Partial<Parameters<typeof MetaTags>[0]> = {}) {
const component = mockComponent({
configuration: {
showSettings: false,
},
});

return renderComponent(
<MetaTags component={component} onComponentChange={jest.fn()} {...overrides} />,
);
function renderMetaTags(componentOverride: Partial<Component> = {}) {
function Component(componentOverride: Partial<Parameters<typeof MetaTags>[0]>) {
const [component, setComponent] = React.useState(
mockComponent({
configuration: {
showSettings: false,
},
...componentOverride,
}),
);

const handleComponentChange = ({ tags }: { tags: string[] }) => {
setComponent((c) => {
return { ...c, tags };
});
};

return <MetaTags component={component} onComponentChange={handleComponentChange} />;
}

return renderComponent(<Component {...componentOverride} />);
}

Loading…
Cancel
Save