Skip to content

Commit

Permalink
Change: Handle delta results with changed severity, qod and hostname (#…
Browse files Browse the repository at this point in the history
…3902)

In addition to description differences, differences in severity,
qod or hostname are considered as a change in delta results comparison.
  • Loading branch information
a-h-abdelsalam authored Oct 19, 2023
1 parent 9275bbd commit 564ecf2
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 14 deletions.
26 changes: 26 additions & 0 deletions src/web/components/icon/deltadifferenceicon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Copyright (C) 2023 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import withSvgIcon from './withSvgIcon';

import {ReactComponent as Icon} from './svg/delta_second.svg';

const DeltaDifferenceIcon = withSvgIcon()(Icon);

export default DeltaDifferenceIcon;

// vim: set ts=2 sw=2 tw=80:
91 changes: 91 additions & 0 deletions src/web/pages/results/__tests__/row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* Copyright (C) 2019-2023 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import {rendererWith} from 'web/utils/testing';
import Row from '../row';
import Result from 'gmp/models/result';

describe('Delta reports V2 with changed severity, qod and hostname', () => {
const {render} = rendererWith();

test('should render Delta Difference icon', () => {
const entity = Result.fromElement({
_id: '101',
name: 'Result 1',
host: {__text: '123.456.78.910', hostname: 'foo'},
port: '80/tcp',
severity: 10.0,
qod: {value: 80},
notes: [],
overrides: [],
tickets: [],
delta: {
result: {
_id: '102',
name: 'Result 2',
host: {__text: '123.456.78.910', hostname: 'bar'},
port: '80/tcp',
severity: 2.6,
qod: {value: 70},
},
},
});

const {getAllByTestId} = render(<Row entity={entity} />);
const icons = getAllByTestId('svg-icon');

expect(icons.length).toEqual(3);
expect(icons[0]).toHaveAttribute('title', 'Severity is changed from 2.6.');
expect(icons[1]).toHaveAttribute('title', 'QoD is changed from 70.');
expect(icons[2]).toHaveAttribute('title', 'Hostname is changed from bar.');
});
});

describe('Delta reports V2 with same severity, qod and hostname', () => {
const {render} = rendererWith();

test('should not render Delta Difference icon', () => {
const entity = Result.fromElement({
_id: '101',
name: 'Result 1',
host: {__text: '123.456.78.910', hostname: 'foo'},
port: '80/tcp',
severity: 10.0,
qod: {value: 80},
notes: [],
overrides: [],
tickets: [],
delta: {
result: {
_id: '102',
name: 'Result 2',
host: {__text: '123.456.78.910', hostname: 'foo'},
port: '80/tcp',
severity: 10.0,
qod: {value: 80},
},
},
});

const {queryAllByTestId} = render(<Row entity={entity} />);
const icons = queryAllByTestId('svg-icon');

expect(icons.length).toBe(0);
});
});
19 changes: 10 additions & 9 deletions src/web/pages/results/details.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ const ResultDetails = ({className, links = true, entity}) => {
</div>
<div>
<h3>{_('Different Lines')}</h3>
{isDefined(result.delta.diff) ? (
{isDefined(result.delta.diff) && result.delta.diff.length > 0 ? (
<Diff>{result.delta.diff}</Diff>
) : (
<DerivedDiff
Expand Down Expand Up @@ -288,14 +288,15 @@ const ResultDetails = ({className, links = true, entity}) => {
<TableRow>
<TableData>{_('Details: ')}</TableData>
<TableData>
{isDefined(infoId) && infoId.startsWith(DEFAULT_OID_VALUE) && (
<span>
<DetailsLink type="nvt" id={infoId} textOnly={!links}>
{renderNvtName(infoId, information.name)}
{' OID: ' + infoId}
</DetailsLink>
</span>
)}
{isDefined(infoId) &&
infoId.startsWith(DEFAULT_OID_VALUE) && (
<span>
<DetailsLink type="nvt" id={infoId} textOnly={!links}>
{renderNvtName(infoId, information.name)}
{' OID: ' + infoId}
</DetailsLink>
</span>
)}
{!isDefined(infoId) &&
_('No details available for this method.')}
</TableData>
Expand Down
42 changes: 37 additions & 5 deletions src/web/pages/results/row.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import SeverityBar from 'web/components/bar/severitybar';

import DateTime from 'web/components/date/datetime';

import DeltaDifferenceIcon from 'web/components/icon/deltadifferenceicon';
import NoteIcon from 'web/components/icon/noteicon';
import OverrideIcon from 'web/components/icon/overrideicon';
import SolutionTypeIcon from 'web/components/icon/solutiontypeicon';
Expand Down Expand Up @@ -68,6 +69,9 @@ const Row = ({
const hasActiveOverrides =
entity.overrides.filter(override => override.isActive()).length > 0;
const hasTickets = entity.tickets.length > 0;
const deltaSeverity = entity.delta?.result?.severity;
const deltaHostname = entity.delta?.result?.host.hostname;
const deltaQoD = entity.delta?.result?.qod.value;
return (
<TableRow>
{delta && (
Expand Down Expand Up @@ -99,10 +103,27 @@ const Row = ({
)}
</TableData>
<TableData>
<SeverityBar severity={entity.severity} />
<IconDivider>
<SeverityBar severity={entity.severity} />
{isDefined(entity.delta?.result) &&
entity.severity !== deltaSeverity && (
<DeltaDifferenceIcon
title={_('Severity is changed from {{deltaSeverity}}.', {
deltaSeverity,
})}
/>
)}
</IconDivider>
</TableData>
<TableData align="end">
<Qod value={entity.qod.value} />
<IconDivider>
<Qod value={entity.qod.value} />
{isDefined(entity.delta?.result) && entity.qod.value !== deltaQoD && (
<DeltaDifferenceIcon
title={_('QoD is changed from {{deltaQoD}}.', {deltaQoD})}
/>
)}
</IconDivider>
</TableData>
<TableData>
<span>
Expand All @@ -116,9 +137,20 @@ const Row = ({
</span>
</TableData>
<TableData>
{host.hostname.length > 0 && (
<span title={host.hostname}>{shorten(host.hostname, 40)}</span>
)}
<IconDivider>
{host.hostname.length > 0 && (
<span title={host.hostname}>{shorten(host.hostname, 40)}</span>
)}
{isDefined(entity.delta?.result) &&
deltaHostname.length > 0 &&
host.hostname !== deltaHostname && (
<DeltaDifferenceIcon
title={_('Hostname is changed from {{deltaHostname}}.', {
deltaHostname,
})}
/>
)}
</IconDivider>
</TableData>
<TableData>{entity.port}</TableData>
<TableData>
Expand Down

0 comments on commit 564ecf2

Please sign in to comment.