Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change: Link to new manual for 24.10 #4289

Merged
merged 10 commits into from
Jan 16, 2025
2 changes: 1 addition & 1 deletion src/gmp/gmpsettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {isDefined} from './utils/identity';
export const DEFAULT_RELOAD_INTERVAL = 15 * 1000; // fifteen seconds
export const DEFAULT_RELOAD_INTERVAL_ACTIVE = 3 * 1000; // three seconds
export const DEFAULT_RELOAD_INTERVAL_INACTIVE = 60 * 1000; // one minute
export const DEFAULT_MANUAL_URL = `https://docs.greenbone.net/GSM-Manual/gos-22.04/`;
export const DEFAULT_MANUAL_URL = `https://docs.greenbone.net/GSM-Manual/gos-24.10/`;
export const DEFAULT_PROTOCOLDOC_URL = `https://docs.greenbone.net/API/GMP/gmp-22.5.html`;
export const DEFAULT_REPORT_RESULTS_THRESHOLD = 25000;
export const DEFAULT_LOG_LEVEL = 'warn';
Expand Down
13 changes: 7 additions & 6 deletions src/web/components/link/__tests__/manuallink.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const createGmp = (settings = {}) => ({

describe('ManualLink tests', () => {
test('should render ManualLink', () => {
const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink page="foo" title="Foo" />);

expect(element).toHaveAttribute('title', 'Foo');
Expand All @@ -28,7 +28,7 @@ describe('ManualLink tests', () => {
});

test('should render with anchor', () => {
const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink anchor="bar" page="foo" />);

expect(element).toHaveAttribute('href', 'http://foo.bar/en/foo.html#bar');
Expand All @@ -37,7 +37,7 @@ describe('ManualLink tests', () => {
});

test('should render search page', () => {
const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink page="search" searchTerm="bar" />);

expect(element).toHaveAttribute(
Expand All @@ -51,7 +51,7 @@ describe('ManualLink tests', () => {
test('should render with german locale', () => {
setLocale('de');

const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink page="foo" title="Foo" />);

expect(element).toHaveAttribute('title', 'Foo');
Expand All @@ -63,7 +63,7 @@ describe('ManualLink tests', () => {
test('should render with english locale', () => {
setLocale('en');

const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink page="foo" title="Foo" />);

expect(element).toHaveAttribute('title', 'Foo');
Expand All @@ -73,7 +73,7 @@ describe('ManualLink tests', () => {
});

test('should render fallback to english locale', () => {
const {render} = rendererWith({gmp: createGmp()});
const {render} = rendererWith({gmp: createGmp(), store: true});
const {element} = render(<ManualLink lang="foo" page="foo" title="Foo" />);

expect(element).toHaveAttribute('title', 'Foo');
Expand All @@ -89,6 +89,7 @@ describe('ManualLink tests', () => {
de: 'foo',
},
}),
store: true,
});
const {element} = render(<ManualLink lang="de" page="foo" title="Foo" />);

Expand Down
38 changes: 7 additions & 31 deletions src/web/components/link/manuallink.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,22 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {getLocale} from 'gmp/locale/lang';
import {isDefined} from 'gmp/utils/identity';
import React from 'react';
import useGmp from 'web/hooks/useGmp';
import useManualURL from 'web/hooks/useManualURL';
import PropTypes from 'web/utils/proptypes';

import BlankLink from './blanklink';

const LANGUAGE_MAPPING = {
de: 'de',
};

const DEFAULT_LANGUAGE_PATH = 'en';

const getLanguagePath = (
lang = getLocale(),
languageMapping = LANGUAGE_MAPPING,
) => {
if (!isDefined(lang)) {
return DEFAULT_LANGUAGE_PATH;
}

const code = lang.slice(0, 2);
const path = languageMapping[code];

return isDefined(path) ? path : DEFAULT_LANGUAGE_PATH;
};

const ManualLink = ({anchor, page, searchTerm, lang, ...props}) => {
const gmp = useGmp();
const {manualUrl, manualLanguageMapping} = gmp.settings;

let url = manualUrl;
if (!url.endsWith('/')) {
url += '/';
}
const ManualLink = ({anchor, page, searchTerm, lang, highlight, ...props}) => {
const manualURL = useManualURL(lang);

url += getLanguagePath(lang, manualLanguageMapping) + '/' + page + '.html';
let url = manualURL + '/' + page + '.html';

if (page === 'search' && isDefined(searchTerm)) {
url += '?q=' + searchTerm;
} else if (isDefined(highlight)) {
url += '?highlight=' + highlight;
} else if (isDefined(anchor)) {
url += '#' + anchor;
}
Expand All @@ -52,6 +27,7 @@ const ManualLink = ({anchor, page, searchTerm, lang, ...props}) => {

ManualLink.propTypes = {
anchor: PropTypes.string,
highlight: PropTypes.string,
lang: PropTypes.string,
page: PropTypes.string.isRequired,
searchTerm: PropTypes.string,
Expand Down
4 changes: 3 additions & 1 deletion src/web/components/menu/menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
import Link from 'web/components/link/link';
import useCapabilities from 'web/hooks/useCapabilities';
import useGmp from 'web/hooks/useGmp';
import useManualURL from 'web/hooks/useManualURL';

Check warning on line 23 in src/web/components/menu/menu.jsx

View check run for this annotation

Codecov / codecov/patch

src/web/components/menu/menu.jsx#L23

Added line #L23 was not covered by tests
import useTranslation from 'web/hooks/useTranslation';

const Menu = () => {
const [_] = useTranslation();
const capabilities = useCapabilities();
const gmp = useGmp();
const manualURL = useManualURL();

Check warning on line 30 in src/web/components/menu/menu.jsx

View check run for this annotation

Codecov / codecov/patch

src/web/components/menu/menu.jsx#L30

Added line #L30 was not covered by tests

function checkCapabilities(capabilitiesList) {
return capabilitiesList.reduce(
Expand Down Expand Up @@ -355,7 +357,7 @@
subNav: [
{
label: _('User Manual'),
to: 'https://docs.greenbone.net/GSM-Manual/gos-22.04/en/',
to: manualURL,

Check warning on line 360 in src/web/components/menu/menu.jsx

View check run for this annotation

Codecov / codecov/patch

src/web/components/menu/menu.jsx#L360

Added line #L360 was not covered by tests
isExternal: true,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import styled from 'styled-components';
import BlankLink from 'web/components/link/blanklink';
import ManualLink from 'web/components/link/manuallink';
import {
useFeedSyncStatus,
useFeedSyncDialog,
Expand Down Expand Up @@ -51,13 +51,14 @@ const FeedSyncNotification = () => {
{_(
`Please wait while the feed is syncing. Scans are not available during this time. For more information, visit the`,
)}{' '}
<BlankLink
to={
'https://docs.greenbone.net/GSM-Manual/gos-21.04/en/scanning.html?highlight=scan'
}
<ManualLink
highlight="scan"
page="scanning"
title={_('Documentation')}
>
{_('Documentation')}.
</BlankLink>
{_('Documentation')}
</ManualLink>
.
</p>
)}
</InfoPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,36 @@

import {describe, test, expect} from '@gsa/testing';
import FeedSyncNotification from 'web/components/notification/FeedSyncNotification/FeedSyncNotification';
import {setSyncStatus, setError} from 'web/store/feedStatus/actions';
import {rendererWith, waitFor, screen} from 'web/utils/testing';

const gmp = {settings: {manualUrl: 'http://localhost/manual'}};

describe('FeedSyncNotification', () => {
test('should display syncing message when feed is syncing', async () => {
const {render, store} = rendererWith({store: true});
const {render, store} = rendererWith({store: true, gmp});

render(<FeedSyncNotification />);

store.dispatch({type: 'SET_SYNC_STATUS', payload: {isSyncing: true}});
store.dispatch(setSyncStatus(true));

await waitFor(() => {
expect(screen.getByText('Feed is currently syncing.')).toBeVisible();
});
expect(
screen.getByText(
'Please wait while the feed is syncing. Scans are not available during this time. For more information, visit the',
/Please wait while the feed is syncing. Scans are not available during this time. For more information, visit the/,
),
).toBeVisible();
expect(screen.getByText('Documentation.')).toBeVisible();
expect(screen.getByText(/Documentation/)).toBeVisible();
});

test('should display error message when there is an error', () => {
const {render, store} = rendererWith({store: true});
const {render, store} = rendererWith({store: true, gmp});

render(<FeedSyncNotification />);

store.dispatch({
type: 'SET_ERROR',
payload: 'Error fetching the feed',
});
store.dispatch(setError('Error fetching the feed'));

expect(screen.getByText('Error fetching the feed')).toBeVisible();
expect(
Expand All @@ -49,8 +48,9 @@ describe('FeedSyncNotification', () => {
),
).toBeVisible();
});

test('should not render anything when isFeedSyncDialogOpened is false', async () => {
const {render} = rendererWith({store: true});
const {render} = rendererWith({store: true, gmp});

render(<FeedSyncNotification />);
expect(screen.queryByText('Feed is currently syncing.')).toBeNull();
Expand Down
73 changes: 73 additions & 0 deletions src/web/hooks/__tests__/useManualURL.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* SPDX-FileCopyrightText: 2025 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {describe, test, expect} from '@gsa/testing';
import {setLocale} from 'web/store/usersettings/actions';
import {rendererWith} from 'web/utils/testing';

import useManualURL from '../useManualURL';

const gmp = {settings: {manualUrl: 'http://localhost/manual'}};

describe('useManualURL', () => {
test('should return the manual URL for the default language', () => {
const {renderHook} = rendererWith({
store: true,
gmp,
});
const {result} = renderHook(() => useManualURL());

expect(result.current).toBe('http://localhost/manual/en');
});

test('should return the manual URL for the German language', () => {
const {renderHook} = rendererWith({
store: true,
gmp,
});
const {result} = renderHook(() => useManualURL('de'));

expect(result.current).toBe('http://localhost/manual/de');
});

test('should return the manual URL for the users language', () => {
const {renderHook, store} = rendererWith({
store: true,
gmp,
});
store.dispatch(setLocale('de'));
const {result} = renderHook(() => useManualURL());

expect(result.current).toBe('http://localhost/manual/de');
});

test('should return the en manual URL for unknown language', () => {
const {renderHook} = rendererWith({
store: true,
gmp,
});
const {result} = renderHook(() => useManualURL('foo'));

expect(result.current).toBe('http://localhost/manual/en');
});

test('should return the en manual URL considering the lanuage mapping', () => {
const {renderHook, store} = rendererWith({
store: true,
gmp: {
settings: {
...gmp.settings,
manualLanguageMapping: {
fr: 'foo',
},
},
},
});
store.dispatch(setLocale('fr'));
const {result} = renderHook(() => useManualURL());

expect(result.current).toBe('http://localhost/manual/foo');
});
});
46 changes: 46 additions & 0 deletions src/web/hooks/useManualURL.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* SPDX-FileCopyrightText: 2025 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {DEFAULT_MANUAL_URL} from 'gmp/gmpsettings';
import {isDefined} from 'gmp/utils/identity';

import useGmp from './useGmp';
import useLocale from './useLocale';

const DEFAULT_LANGUAGE_MAPPING = {
de: 'de',
};

const DEFAULT_LANGUAGE_PATH = 'en';

const getLanguagePath = (locale, languageMapping) => {
if (!isDefined(locale)) {
return DEFAULT_LANGUAGE_PATH;
}

const code = locale.slice(0, 2);
const path = languageMapping[code];

return isDefined(path) ? path : DEFAULT_LANGUAGE_PATH;
};

const useManualURL = locale => {
const [userLocale] = useLocale();
const gmp = useGmp();
const {
manualUrl = DEFAULT_MANUAL_URL,
manualLanguageMapping = DEFAULT_LANGUAGE_MAPPING,
} = gmp.settings;

const baseUrl = manualUrl.endsWith('/') ? manualUrl : `${manualUrl}/`;
const languagePath = getLanguagePath(
locale || userLocale,
manualLanguageMapping,
);

return `${baseUrl}${languagePath}`;
};

export default useManualURL;
2 changes: 1 addition & 1 deletion src/web/utils/testing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const TestingLicenseProvider = withProvider(
)(LicenseProvider);

export const rendererWith = (
{capabilities, gmp, license, store, router} = {
{capabilities, gmp, license, store = true, router} = {
store: true,
router: true,
},
Expand Down
Loading