diff --git a/src/web/pages/reports/details/__tests__/resultstab.js b/src/web/pages/reports/details/__tests__/resultstab.js
new file mode 100644
index 0000000000..45764c520e
--- /dev/null
+++ b/src/web/pages/reports/details/__tests__/resultstab.js
@@ -0,0 +1,387 @@
+/* Copyright (C) 2024 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 {setLocale} from 'gmp/locale/lang';
+
+import Filter from 'gmp/models/filter';
+
+import {setTimezone, setUsername} from 'web/store/usersettings/actions';
+import CollectionCounts from 'gmp/collection/collectioncounts';
+
+import {rendererWith, wait} from 'web/utils/testing';
+import Result from 'gmp/models/result';
+import {loadingActions} from 'web/store/usersettings/defaults/actions';
+import {defaultFilterLoadingActions} from 'web/store/usersettings/defaultfilters/actions';
+import {entitiesLoadingActions} from 'web/store/entities/results';
+
+import ResultsTab from '../resultstab';
+
+setLocale('en');
+
+const reloadInterval = 1;
+const manualUrl = 'test/';
+
+// mock entities
+export const result1 = Result.fromElement({
+ _id: '101',
+ name: 'Result 1',
+ owner: {name: 'admin'},
+ comment: 'Comment 1',
+ creation_time: '2019-06-03T11:06:31Z',
+ modification_time: '2019-06-03T11:06:31Z',
+ host: {__text: '123.456.78.910', hostname: 'foo'},
+ port: '80/tcp',
+ nvt: {
+ _oid: '201',
+ type: 'nvt',
+ name: 'nvt1',
+ tags: 'solution_type=Mitigation',
+ refs: {ref: [{_type: 'cve', _id: 'CVE-2019-1234'}]},
+ },
+ threat: 'High',
+ severity: 10.0,
+ qod: {value: 80},
+ compliance: 'yes',
+});
+
+export const result2 = Result.fromElement({
+ _id: '102',
+ name: 'Result 2',
+ owner: {name: 'admin'},
+ comment: 'Comment 2',
+ creation_time: '2019-06-03T11:06:31Z',
+ modification_time: '2019-06-03T11:06:31Z',
+ host: {__text: '109.876.54.321'},
+ port: '80/tcp',
+ nvt: {
+ _oid: '202',
+ type: 'nvt',
+ name: 'nvt2',
+ tags: 'solution_type=VendorFix',
+ refs: {ref: [{_type: 'cve', _id: 'CVE-2019-5678'}]},
+ },
+ threat: 'Medium',
+ severity: 5.0,
+ qod: {value: 70},
+ compliance: 'no',
+});
+
+export const result3 = Result.fromElement({
+ _id: '103',
+ name: 'Result 3',
+ owner: {name: 'admin'},
+ comment: 'Comment 3',
+ creation_time: '2019-06-03T11:06:31Z',
+ modification_time: '2019-06-03T11:06:31Z',
+ host: {__text: '109.876.54.321', hostname: 'bar'},
+ port: '80/tcp',
+ nvt: {
+ _oid: '201',
+ type: 'nvt',
+ name: 'nvt1',
+ tags: 'solution_type=Mitigation',
+ refs: {ref: [{_type: 'cve', _id: 'CVE-2019-1234'}]},
+ solution: {
+ _type: 'Mitigation',
+ },
+ },
+ threat: 'Medium',
+ severity: 5.0,
+ qod: {value: 80},
+ compliance: 'incomplete',
+});
+
+const results = [result1, result2, result3];
+
+let currentSettings;
+let getAggregates;
+let getDashboardSetting;
+let getFilters;
+let getResults;
+
+beforeEach(() => {
+ // mock gmp commands
+
+ getResults = jest.fn().mockResolvedValue({
+ data: results,
+ meta: {
+ filter: Filter.fromString(),
+ counts: new CollectionCounts(),
+ },
+ });
+
+ getFilters = jest.fn().mockReturnValue(
+ Promise.resolve({
+ data: [],
+ meta: {
+ filter: Filter.fromString(),
+ counts: new CollectionCounts(),
+ },
+ }),
+ );
+
+ getDashboardSetting = jest.fn().mockResolvedValue({
+ data: [],
+ meta: {
+ filter: Filter.fromString(),
+ counts: new CollectionCounts(),
+ },
+ });
+
+ getAggregates = jest.fn().mockResolvedValue({
+ data: [],
+ meta: {
+ filter: Filter.fromString(),
+ counts: new CollectionCounts(),
+ },
+ });
+
+ currentSettings = jest.fn().mockResolvedValue({
+ foo: 'bar',
+ });
+});
+
+describe('Report Results Tab tests', () => {
+ test('should render Results Tab with compliance information', async () => {
+ const reload = jest.fn();
+ const onFilterAddLogLevelClick = jest.fn();
+ const onFilterDecreaseMinQoDClick = jest.fn();
+ const onFilterEditClick = jest.fn();
+ const onFilterRemoveClick = jest.fn();
+ const onFilterRemoveSeverityClick = jest.fn();
+ const onTargetEditClick = jest.fn();
+
+ const gmp = {
+ results: {
+ get: getResults,
+ getSeverityAggregates: getAggregates,
+ getWordCountsAggregates: getAggregates,
+ },
+ filters: {
+ get: getFilters,
+ },
+ dashboard: {
+ getSetting: getDashboardSetting,
+ },
+ settings: {manualUrl, reloadInterval},
+ user: {currentSettings},
+ };
+
+ const {render, store} = rendererWith({
+ gmp,
+ capabilities: true,
+ store: true,
+ router: true,
+ });
+
+ store.dispatch(setTimezone('CET'));
+ store.dispatch(setUsername('admin'));
+
+ const defaultSettingfilter = Filter.fromString('foo=bar');
+ store.dispatch(loadingActions.success({rowsperpage: {value: '2'}}));
+ store.dispatch(
+ defaultFilterLoadingActions.success('result', defaultSettingfilter),
+ );
+
+ const counts = new CollectionCounts({
+ first: 1,
+ all: 1,
+ filtered: 1,
+ length: 1,
+ rows: 10,
+ });
+ const filter = Filter.fromString('first=1 rows=10');
+ const loadedFilter = Filter.fromString('first=1 rows=10');
+ store.dispatch(
+ entitiesLoadingActions.success(results, filter, loadedFilter, counts),
+ );
+
+ const {baseElement} = render(
+ ,
+ );
+
+ await wait();
+
+ const header = baseElement.querySelectorAll('th');
+ const row = baseElement.querySelectorAll('tr');
+
+ expect(header[0]).toHaveTextContent('Vulnerability');
+ expect(header[1]).toHaveTextContent('solution_type.svg');
+ expect(header[2]).toHaveTextContent('Compliant');
+ expect(header[3]).toHaveTextContent('QoD');
+ expect(header[4]).toHaveTextContent('Host');
+ expect(header[5]).toHaveTextContent('Location');
+ expect(header[6]).toHaveTextContent('Created');
+ expect(header[7]).toHaveTextContent('IP');
+ expect(header[8]).toHaveTextContent('Name');
+
+ expect(row[2]).toHaveTextContent('Result 1');
+ expect(row[2]).toHaveTextContent('Yes');
+ expect(row[2]).toHaveTextContent('80 %');
+ expect(row[2]).toHaveTextContent('123.456.78.910');
+ expect(row[2]).toHaveTextContent('foo');
+ expect(row[2]).toHaveTextContent('80/tcp');
+ expect(row[2]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+
+ expect(row[3]).toHaveTextContent('Result 2');
+ expect(row[3]).toHaveTextContent('No');
+ expect(row[3]).toHaveTextContent('70 %');
+ expect(row[3]).toHaveTextContent('109.876.54.321');
+ expect(row[3]).toHaveTextContent('80/tcp');
+ expect(row[3]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+
+ expect(row[4]).toHaveTextContent('Result 3');
+ expect(row[4]).toHaveTextContent('st_mitigate.svg');
+ expect(row[4]).toHaveTextContent('Incomplete');
+ expect(row[4]).toHaveTextContent('80 %');
+ expect(row[4]).toHaveTextContent('109.876.54.321');
+ expect(row[4]).toHaveTextContent('bar');
+ expect(row[4]).toHaveTextContent('80/tcp');
+ expect(row[4]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+ });
+
+ test('should render Results Tab with compliance information', async () => {
+ const reload = jest.fn();
+ const onFilterAddLogLevelClick = jest.fn();
+ const onFilterDecreaseMinQoDClick = jest.fn();
+ const onFilterEditClick = jest.fn();
+ const onFilterRemoveClick = jest.fn();
+ const onFilterRemoveSeverityClick = jest.fn();
+ const onTargetEditClick = jest.fn();
+
+ const gmp = {
+ results: {
+ get: getResults,
+ getSeverityAggregates: getAggregates,
+ getWordCountsAggregates: getAggregates,
+ },
+ filters: {
+ get: getFilters,
+ },
+ dashboard: {
+ getSetting: getDashboardSetting,
+ },
+ settings: {manualUrl, reloadInterval},
+ user: {currentSettings},
+ };
+
+ const {render, store} = rendererWith({
+ gmp,
+ capabilities: true,
+ store: true,
+ router: true,
+ });
+
+ store.dispatch(setTimezone('CET'));
+ store.dispatch(setUsername('admin'));
+
+ const defaultSettingfilter = Filter.fromString('foo=bar');
+ store.dispatch(loadingActions.success({rowsperpage: {value: '2'}}));
+ store.dispatch(
+ defaultFilterLoadingActions.success('result', defaultSettingfilter),
+ );
+
+ const counts = new CollectionCounts({
+ first: 1,
+ all: 1,
+ filtered: 1,
+ length: 1,
+ rows: 10,
+ });
+ const filter = Filter.fromString('first=1 rows=10');
+ const loadedFilter = Filter.fromString('first=1 rows=10');
+ store.dispatch(
+ entitiesLoadingActions.success(results, filter, loadedFilter, counts),
+ );
+
+ const {baseElement} = render(
+ ,
+ );
+
+ await wait();
+
+ const header = baseElement.querySelectorAll('th');
+ const row = baseElement.querySelectorAll('tr');
+
+ expect(header[0]).toHaveTextContent('Vulnerability');
+ expect(header[1]).toHaveTextContent('solution_type.svg');
+ expect(header[2]).toHaveTextContent('Severity');
+ expect(header[3]).toHaveTextContent('QoD');
+ expect(header[4]).toHaveTextContent('Host');
+ expect(header[5]).toHaveTextContent('Location');
+ expect(header[6]).toHaveTextContent('Created');
+ expect(header[7]).toHaveTextContent('IP');
+ expect(header[8]).toHaveTextContent('Name');
+
+ expect(row[2]).toHaveTextContent('Result 1');
+ expect(row[2]).toHaveTextContent('10.0 (High)');
+ expect(row[2]).toHaveTextContent('80 %');
+ expect(row[2]).toHaveTextContent('123.456.78.910');
+ expect(row[2]).toHaveTextContent('foo');
+ expect(row[2]).toHaveTextContent('80/tcp');
+ expect(row[2]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+
+ expect(row[3]).toHaveTextContent('Result 2');
+ expect(row[3]).toHaveTextContent('5.0 (Medium)');
+ expect(row[3]).toHaveTextContent('70 %');
+ expect(row[3]).toHaveTextContent('109.876.54.321');
+ expect(row[3]).toHaveTextContent('80/tcp');
+ expect(row[3]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+
+ expect(row[4]).toHaveTextContent('Result 3');
+ expect(row[4]).toHaveTextContent('st_mitigate.svg');
+ expect(row[4]).toHaveTextContent('5.0 (Medium)');
+ expect(row[4]).toHaveTextContent('80 %');
+ expect(row[4]).toHaveTextContent('109.876.54.321');
+ expect(row[4]).toHaveTextContent('bar');
+ expect(row[4]).toHaveTextContent('80/tcp');
+ expect(row[4]).toHaveTextContent('Mon, Jun 3, 2019 1:06 PM CEST');
+ });
+});