diff --git a/src/web/components/icon/deltadifferenceicon.js b/src/web/components/icon/deltadifferenceicon.js new file mode 100644 index 0000000000..f55d54e50a --- /dev/null +++ b/src/web/components/icon/deltadifferenceicon.js @@ -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 . + */ +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: diff --git a/src/web/pages/results/__tests__/row.js b/src/web/pages/results/__tests__/row.js new file mode 100644 index 0000000000..0449771c3b --- /dev/null +++ b/src/web/pages/results/__tests__/row.js @@ -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 . + */ + +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(); + 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(); + const icons = queryAllByTestId('svg-icon'); + + expect(icons.length).toBe(0); + }); +}); diff --git a/src/web/pages/results/details.js b/src/web/pages/results/details.js index 5a439bff9f..7ad40dbbc7 100644 --- a/src/web/pages/results/details.js +++ b/src/web/pages/results/details.js @@ -186,7 +186,7 @@ const ResultDetails = ({className, links = true, entity}) => {

{_('Different Lines')}

- {isDefined(result.delta.diff) ? ( + {isDefined(result.delta.diff) && result.delta.diff.length > 0 ? ( {result.delta.diff} ) : ( { {_('Details: ')} - {isDefined(infoId) && infoId.startsWith(DEFAULT_OID_VALUE) && ( - - - {renderNvtName(infoId, information.name)} - {' OID: ' + infoId} - - - )} + {isDefined(infoId) && + infoId.startsWith(DEFAULT_OID_VALUE) && ( + + + {renderNvtName(infoId, information.name)} + {' OID: ' + infoId} + + + )} {!isDefined(infoId) && _('No details available for this method.')} diff --git a/src/web/pages/results/row.js b/src/web/pages/results/row.js index 5557d5f217..9be9d5a693 100644 --- a/src/web/pages/results/row.js +++ b/src/web/pages/results/row.js @@ -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'; @@ -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 ( {delta && ( @@ -99,10 +103,27 @@ const Row = ({ )} - + + + {isDefined(entity.delta?.result) && + entity.severity !== deltaSeverity && ( + + )} + - + + + {isDefined(entity.delta?.result) && entity.qod.value !== deltaQoD && ( + + )} + @@ -116,9 +137,20 @@ const Row = ({ - {host.hostname.length > 0 && ( - {shorten(host.hostname, 40)} - )} + + {host.hostname.length > 0 && ( + {shorten(host.hostname, 40)} + )} + {isDefined(entity.delta?.result) && + deltaHostname.length > 0 && + host.hostname !== deltaHostname && ( + + )} + {entity.port}