themeBorder,
themeColor,
} from 'design-system';
+import { isEmpty } from 'lodash';
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import Favorite from '../../../../components/controls/Favorite';
isNewCode: boolean,
) {
const { analysisDate, isFavorite, key, measures, name, qualifier, tags, visibility } = project;
+ const awaitingScan =
+ [
+ MetricKey.reliability_issues,
+ MetricKey.maintainability_issues,
+ MetricKey.security_issues,
+ ].every((key) => measures[key] === undefined) &&
+ !isNewCode &&
+ !isEmpty(analysisDate) &&
+ measures.ncloc !== undefined;
const formatted = formatMeasure(measures[MetricKey.alert_status], MetricType.Level);
const qualityGateLabel = translateWithParameters('overview.quality_gate_x', formatted);
return (
<Badge className="sw-ml-2">{translate('visibility', visibility)}</Badge>
</span>
</Tooltip>
+
+ {awaitingScan && !isNewCode && !isEmpty(analysisDate) && measures.ncloc !== undefined && (
+ <Tooltip overlay={translate(`projects.awaiting_scan.description.${qualifier}`)}>
+ <span>
+ <Badge variant="new" className="sw-ml-2">
+ {translate('projects.awaiting_scan')}
+ </Badge>
+ </span>
+ </Tooltip>
+ )}
</div>
{isDefined(analysisDate) && analysisDate !== '' && (
) {
const { analysisDate, key, leakPeriodDate, measures, qualifier, isScannable } = project;
- if (
- isDefined(analysisDate) &&
- analysisDate !== '' &&
- (!isNewCode || (isDefined(leakPeriodDate) && leakPeriodDate !== ''))
- ) {
+ if (!isEmpty(analysisDate) && (!isNewCode || !isEmpty(leakPeriodDate))) {
return (
<ProjectCardMeasures
measures={measures}
</Note>
{qualifier !== ComponentQualifier.Application &&
- (analysisDate === undefined || analysisDate === '') &&
+ isEmpty(analysisDate) &&
isLoggedIn(currentUser) &&
isScannable && (
<Link className="sw-ml-2 sw-body-sm-highlight" to={getProjectUrl(key)}>
{
iconLabel: translate(`metric.${MetricKey.security_issues}.short_name`),
noShrink: true,
- metricKey: MetricKey.security_issues,
+ metricKey:
+ measures[MetricKey.security_issues] !== undefined
+ ? MetricKey.security_issues
+ : MetricKey.vulnerabilities,
metricRatingKey: MetricKey.security_rating,
metricType: MetricType.ShortInteger,
},
{
iconLabel: translate(`metric.${MetricKey.reliability_issues}.short_name`),
- metricKey: MetricKey.reliability_issues,
+ metricKey:
+ measures[MetricKey.reliability_issues] !== undefined
+ ? MetricKey.reliability_issues
+ : MetricKey.bugs,
metricRatingKey: MetricKey.reliability_rating,
metricType: MetricType.ShortInteger,
},
{
iconLabel: translate(`metric.${MetricKey.maintainability_issues}.short_name`),
- metricKey: MetricKey.maintainability_issues,
+ metricKey:
+ measures[MetricKey.maintainability_issues] !== undefined
+ ? MetricKey.maintainability_issues
+ : MetricKey.code_smells,
metricRatingKey: MetricKey.sqale_rating,
metricType: MetricType.ShortInteger,
},
import { mockCurrentUser, mockLoggedInUser } from '../../../../../helpers/testMocks';
import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
import { ComponentQualifier, Visibility } from '../../../../../types/component';
+import { MetricKey } from '../../../../../types/metrics';
import { CurrentUser } from '../../../../../types/users';
import { Project } from '../../../types';
import ProjectCard from '../ProjectCard';
const MEASURES = {
- alert_status: 'OK',
- reliability_rating: '1.0',
- sqale_rating: '1.0',
- new_bugs: '12',
+ [MetricKey.ncloc]: '1000',
+ [MetricKey.alert_status]: 'OK',
+ [MetricKey.reliability_rating]: '1.0',
+ [MetricKey.security_rating]: '1.0',
+ [MetricKey.sqale_rating]: '1.0',
+ [MetricKey.new_bugs]: '12',
};
const PROJECT: Project = {
expect(screen.getByLabelText('qualifier.APP')).toBeInTheDocument();
});
+it('should not display awaiting analysis badge and do not display old measures', () => {
+ renderProjectCard({
+ ...PROJECT,
+ measures: {
+ ...MEASURES,
+ [MetricKey.security_issues]: JSON.stringify({ LOW: 0, MEDIUM: 0, HIGH: 1, total: 1 }),
+ [MetricKey.reliability_issues]: JSON.stringify({ LOW: 0, MEDIUM: 2, HIGH: 0, total: 2 }),
+ [MetricKey.maintainability_issues]: JSON.stringify({ LOW: 3, MEDIUM: 0, HIGH: 0, total: 3 }),
+ [MetricKey.code_smells]: '4',
+ [MetricKey.bugs]: '5',
+ [MetricKey.vulnerabilities]: '6',
+ },
+ });
+ expect(screen.queryByRole('status', { name: 'projects.awaiting_scan' })).not.toBeInTheDocument();
+ expect(screen.getByText('1')).toBeInTheDocument();
+ expect(screen.getByText('2')).toBeInTheDocument();
+ expect(screen.getByText('3')).toBeInTheDocument();
+ expect(screen.queryByText('4')).not.toBeInTheDocument();
+ expect(screen.queryByText('5')).not.toBeInTheDocument();
+ expect(screen.queryByText('6')).not.toBeInTheDocument();
+});
+
+it('should display awaiting analysis badge and show the old measures', async () => {
+ renderProjectCard({
+ ...PROJECT,
+ measures: {
+ ...MEASURES,
+ [MetricKey.code_smells]: '4',
+ [MetricKey.bugs]: '5',
+ [MetricKey.vulnerabilities]: '6',
+ },
+ });
+ expect(screen.getByRole('status', { name: 'projects.awaiting_scan' })).toBeInTheDocument();
+ await expect(
+ screen.getByRole('status', { name: 'projects.awaiting_scan' }),
+ ).toHaveATooltipWithContent('projects.awaiting_scan.description.TRK');
+ expect(screen.getByText('4')).toBeInTheDocument();
+ expect(screen.getByText('5')).toBeInTheDocument();
+ expect(screen.getByText('6')).toBeInTheDocument();
+});
+
+it('should display awaiting analysis badge and show the old measures for Application', async () => {
+ renderProjectCard({
+ ...PROJECT,
+ qualifier: ComponentQualifier.Application,
+ measures: {
+ ...MEASURES,
+ [MetricKey.code_smells]: '4',
+ [MetricKey.bugs]: '5',
+ [MetricKey.vulnerabilities]: '6',
+ },
+ });
+ expect(screen.getByRole('status', { name: 'projects.awaiting_scan' })).toBeInTheDocument();
+ await expect(
+ screen.getByRole('status', { name: 'projects.awaiting_scan' }),
+ ).toHaveATooltipWithContent('projects.awaiting_scan.description.APP');
+ expect(screen.getByText('4')).toBeInTheDocument();
+ expect(screen.getByText('5')).toBeInTheDocument();
+ expect(screen.getByText('6')).toBeInTheDocument();
+});
+
+it('should not display awaiting analysis badge if project is not analyzed', () => {
+ renderProjectCard({
+ ...PROJECT,
+ analysisDate: undefined,
+ });
+ expect(screen.queryByRole('status', { name: 'projects.awaiting_scan' })).not.toBeInTheDocument();
+});
+
+it('should not display awaiting analysis badge if project does not have lines of code', () => {
+ renderProjectCard({
+ ...PROJECT,
+ measures: {
+ ...(({ [MetricKey.ncloc]: _, ...rest }) => rest)(MEASURES),
+ },
+ });
+ expect(screen.queryByRole('status', { name: 'projects.awaiting_scan' })).not.toBeInTheDocument();
+});
+
+it('should not display awaiting analysis badge if it is a new code filter', () => {
+ renderProjectCard(PROJECT, undefined, 'leak');
+ expect(screen.queryByRole('status', { name: 'projects.awaiting_scan' })).not.toBeInTheDocument();
+});
+
it('should display 3 aplication', () => {
renderProjectCard({
...PROJECT,