From 564ecf2fb02b766741a17796c245ae2e5903a88e Mon Sep 17 00:00:00 2001
From: Ahmed <144101267+a-h-abdelsalam@users.noreply.github.com>
Date: Thu, 19 Oct 2023 11:09:16 +0200
Subject: [PATCH] Change: Handle delta results with changed severity, qod and
hostname (#3902)
In addition to description differences, differences in severity,
qod or hostname are considered as a change in delta results comparison.
---
.../components/icon/deltadifferenceicon.js | 26 ++++++
src/web/pages/results/__tests__/row.js | 91 +++++++++++++++++++
src/web/pages/results/details.js | 19 ++--
src/web/pages/results/row.js | 42 ++++++++-
4 files changed, 164 insertions(+), 14 deletions(-)
create mode 100644 src/web/components/icon/deltadifferenceicon.js
create mode 100644 src/web/pages/results/__tests__/row.js
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}