Merge branch 'master' into issues/2752
This commit is contained in:
commit
f9ba69dc71
9 changed files with 62 additions and 161 deletions
|
@ -1,52 +1,38 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import WarningIcon from 'components/common/Icons/WarningIcon';
|
import WarningIcon from 'components/common/Icons/WarningIcon';
|
||||||
import { gitCommitPath } from 'lib/paths';
|
import { gitCommitPath } from 'lib/paths';
|
||||||
import { useActuatorInfo } from 'lib/hooks/api/actuatorInfo';
|
|
||||||
import { BUILD_VERSION_PATTERN } from 'lib/constants';
|
|
||||||
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
|
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
|
||||||
import { formatTimestamp } from 'lib/dateTimeHelpers';
|
import { formatTimestamp } from 'lib/dateTimeHelpers';
|
||||||
|
|
||||||
import * as S from './Version.styled';
|
import * as S from './Version.styled';
|
||||||
import compareVersions from './compareVersions';
|
|
||||||
|
|
||||||
const Version: React.FC = () => {
|
const Version: React.FC = () => {
|
||||||
const { data: actuatorInfo = {} } = useActuatorInfo();
|
|
||||||
const { data: latestVersionInfo = {} } = useLatestVersion();
|
const { data: latestVersionInfo = {} } = useLatestVersion();
|
||||||
|
const { buildTime, commitId, isLatestRelease } = latestVersionInfo.build;
|
||||||
const tag = actuatorInfo?.build?.version;
|
const { versionTag } = latestVersionInfo?.latestRelease || '';
|
||||||
const commit = actuatorInfo?.git?.commit.id;
|
|
||||||
const { tag_name: latestTag } = latestVersionInfo;
|
|
||||||
|
|
||||||
const outdated = compareVersions(tag, latestTag);
|
|
||||||
|
|
||||||
const currentVersion = tag?.match(BUILD_VERSION_PATTERN)
|
|
||||||
? tag
|
|
||||||
: formatTimestamp(actuatorInfo?.build?.time);
|
|
||||||
|
|
||||||
if (!tag) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<S.Wrapper>
|
<S.Wrapper>
|
||||||
{!!outdated && (
|
{!isLatestRelease && (
|
||||||
<S.OutdatedWarning
|
<S.OutdatedWarning
|
||||||
title={`Your app version is outdated. Current latest version is ${latestTag}`}
|
title={`Your app version is outdated. Current latest version is ${versionTag}`}
|
||||||
>
|
>
|
||||||
<WarningIcon />
|
<WarningIcon />
|
||||||
</S.OutdatedWarning>
|
</S.OutdatedWarning>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{commit && (
|
{commitId && (
|
||||||
<div>
|
<div>
|
||||||
<S.CurrentCommitLink
|
<S.CurrentCommitLink
|
||||||
title="Current commit"
|
title="Current commit"
|
||||||
target="__blank"
|
target="__blank"
|
||||||
href={gitCommitPath(commit)}
|
href={gitCommitPath(commitId)}
|
||||||
>
|
>
|
||||||
{commit}
|
{commitId}
|
||||||
</S.CurrentCommitLink>
|
</S.CurrentCommitLink>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<S.CurrentVersion>{currentVersion}</S.CurrentVersion>
|
<S.CurrentVersion>{formatTimestamp(buildTime)}</S.CurrentVersion>
|
||||||
</S.Wrapper>
|
</S.Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,87 +2,40 @@ import React from 'react';
|
||||||
import { screen } from '@testing-library/dom';
|
import { screen } from '@testing-library/dom';
|
||||||
import Version from 'components/Version/Version';
|
import Version from 'components/Version/Version';
|
||||||
import { render } from 'lib/testHelpers';
|
import { render } from 'lib/testHelpers';
|
||||||
import { formatTimestamp } from 'lib/dateTimeHelpers';
|
|
||||||
import { useActuatorInfo } from 'lib/hooks/api/actuatorInfo';
|
|
||||||
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
|
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
|
||||||
import { actuatorInfoPayload } from 'lib/fixtures/actuatorInfo';
|
import {
|
||||||
import { latestVersionPayload } from 'lib/fixtures/latestVersion';
|
deprecatedVersionPayload,
|
||||||
|
latestVersionPayload,
|
||||||
|
} from 'lib/fixtures/latestVersion';
|
||||||
|
|
||||||
jest.mock('lib/hooks/api/actuatorInfo', () => ({
|
|
||||||
useActuatorInfo: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('lib/hooks/api/latestVersion', () => ({
|
jest.mock('lib/hooks/api/latestVersion', () => ({
|
||||||
useLatestVersion: jest.fn(),
|
useLatestVersion: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('Version Component', () => {
|
describe('Version Component', () => {
|
||||||
const versionTag = 'v0.5.0';
|
const commitId = '96a577a';
|
||||||
const snapshotTag = 'test-SNAPSHOT';
|
|
||||||
const commitTag = 'befd3b328e2c9c7df57b0c5746561b2f7fee8813';
|
|
||||||
|
|
||||||
const actuatorVersionPayload = actuatorInfoPayload(versionTag);
|
|
||||||
const formattedTimestamp = formatTimestamp(actuatorVersionPayload.build.time);
|
|
||||||
|
|
||||||
|
describe('render latest version', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
|
|
||||||
data: actuatorVersionPayload,
|
|
||||||
}));
|
|
||||||
(useLatestVersion as jest.Mock).mockImplementation(() => ({
|
(useLatestVersion as jest.Mock).mockImplementation(() => ({
|
||||||
data: latestVersionPayload,
|
data: latestVersionPayload,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
it('renders latest release version as current version', async () => {
|
||||||
|
render(<Version />);
|
||||||
|
expect(screen.getByText(commitId)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
describe('tag does not exist', () => {
|
it('should not show warning icon if it is last release', async () => {
|
||||||
it('does not render component', async () => {
|
render(<Version />);
|
||||||
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
|
expect(screen.queryByRole('img')).not.toBeInTheDocument();
|
||||||
data: null,
|
|
||||||
}));
|
|
||||||
const { container } = render(<Version />);
|
|
||||||
expect(container.firstChild).toBeEmptyDOMElement();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('renders current version', () => {
|
it('show warning icon if it is not last release', async () => {
|
||||||
it('renders release build version as current version', async () => {
|
(useLatestVersion as jest.Mock).mockImplementation(() => ({
|
||||||
render(<Version />);
|
data: deprecatedVersionPayload,
|
||||||
expect(screen.getByText(versionTag)).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
it('renders formatted timestamp as current version when version is commit', async () => {
|
|
||||||
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
|
|
||||||
data: actuatorInfoPayload(commitTag),
|
|
||||||
}));
|
}));
|
||||||
render(<Version />);
|
render(<Version />);
|
||||||
expect(screen.getByText(formattedTimestamp)).toBeInTheDocument();
|
expect(screen.getByRole('img')).toBeInTheDocument();
|
||||||
});
|
|
||||||
it('renders formatted timestamp as current version when version contains -SNAPSHOT', async () => {
|
|
||||||
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
|
|
||||||
data: actuatorInfoPayload(snapshotTag),
|
|
||||||
}));
|
|
||||||
render(<Version />);
|
|
||||||
expect(screen.getByText(formattedTimestamp)).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('outdated build version', () => {
|
|
||||||
it('renders warning message', async () => {
|
|
||||||
(useActuatorInfo as jest.Mock).mockImplementation(() => ({
|
|
||||||
data: actuatorInfoPayload('v0.3.0'),
|
|
||||||
}));
|
|
||||||
render(<Version />);
|
|
||||||
expect(
|
|
||||||
screen.getByTitle(
|
|
||||||
`Your app version is outdated. Current latest version is ${latestVersionPayload.tag_name}`
|
|
||||||
)
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('current commit id with link', () => {
|
|
||||||
it('renders', async () => {
|
|
||||||
render(<Version />);
|
|
||||||
expect(
|
|
||||||
screen.getByText(actuatorVersionPayload.git.commit.id)
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,7 @@ const WarningIcon: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<WarningIconContainer>
|
<WarningIconContainer>
|
||||||
<svg
|
<svg
|
||||||
|
role="img"
|
||||||
width="14"
|
width="14"
|
||||||
height="13"
|
height="13"
|
||||||
viewBox="0 0 14 13"
|
viewBox="0 0 14 13"
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
export const actuatorInfoPayload = (
|
|
||||||
version = 'befd3b328e2c9c7df57b0c5746561b2f7fee8813'
|
|
||||||
) => ({
|
|
||||||
git: { commit: { id: 'befd3b3' } },
|
|
||||||
build: {
|
|
||||||
artifact: 'kafka-ui-api',
|
|
||||||
name: 'kafka-ui-api',
|
|
||||||
time: '2022-09-15T09:52:21.753Z',
|
|
||||||
version,
|
|
||||||
group: 'com.provectus',
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,3 +1,16 @@
|
||||||
export const latestVersionPayload = {
|
export const deprecatedVersionPayload = {
|
||||||
tag_name: 'v0.4.0',
|
build: {
|
||||||
|
buildTime: '2023-04-14T09:47:35.463Z',
|
||||||
|
commitId: '96a577a',
|
||||||
|
isLatestRelease: false,
|
||||||
|
version: '96a577a98c6069376c5d22ed49cffd3739f1bbdc',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const latestVersionPayload = {
|
||||||
|
build: {
|
||||||
|
buildTime: '2023-04-14T09:47:35.463Z',
|
||||||
|
commitId: '96a577a',
|
||||||
|
isLatestRelease: true,
|
||||||
|
version: '96a577a98c6069376c5d22ed49cffd3739f1bbdc',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import fetchMock from 'fetch-mock';
|
|
||||||
import * as hooks from 'lib/hooks/api/actuatorInfo';
|
|
||||||
import { expectQueryWorks, renderQueryHook } from 'lib/testHelpers';
|
|
||||||
import { actuatorInfoPayload } from 'lib/fixtures/actuatorInfo';
|
|
||||||
|
|
||||||
const actuatorInfoPath = '/actuator/info';
|
|
||||||
|
|
||||||
describe('Actuator info hooks', () => {
|
|
||||||
beforeEach(() => fetchMock.restore());
|
|
||||||
describe('useActuatorInfo', () => {
|
|
||||||
it('returns the correct data', async () => {
|
|
||||||
const mock = fetchMock.getOnce(actuatorInfoPath, actuatorInfoPayload());
|
|
||||||
const { result } = renderQueryHook(() => hooks.useActuatorInfo());
|
|
||||||
await expectQueryWorks(mock, result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,18 +1,16 @@
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
import { expectQueryWorks, renderQueryHook } from 'lib/testHelpers';
|
import { expectQueryWorks, renderQueryHook } from 'lib/testHelpers';
|
||||||
import * as hooks from 'lib/hooks/api/latestVersion';
|
|
||||||
import { GIT_REPO_LATEST_RELEASE_LINK } from 'lib/constants';
|
|
||||||
import { latestVersionPayload } from 'lib/fixtures/latestVersion';
|
import { latestVersionPayload } from 'lib/fixtures/latestVersion';
|
||||||
|
import { useLatestVersion } from 'lib/hooks/api/latestVersion';
|
||||||
|
|
||||||
|
const latestVersionPath = '/api/info';
|
||||||
|
|
||||||
describe('Latest version hooks', () => {
|
describe('Latest version hooks', () => {
|
||||||
beforeEach(() => fetchMock.restore());
|
beforeEach(() => fetchMock.restore());
|
||||||
describe('useLatestVersion', () => {
|
describe('useLatestVersion', () => {
|
||||||
it('returns the correct data', async () => {
|
it('returns the correct data', async () => {
|
||||||
const mock = fetchMock.getOnce(
|
const mock = fetchMock.getOnce(latestVersionPath, latestVersionPayload);
|
||||||
GIT_REPO_LATEST_RELEASE_LINK,
|
const { result } = renderQueryHook(() => useLatestVersion());
|
||||||
latestVersionPayload
|
|
||||||
);
|
|
||||||
const { result } = renderQueryHook(() => hooks.useLatestVersion());
|
|
||||||
await expectQueryWorks(mock, result);
|
await expectQueryWorks(mock, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { BASE_PARAMS, QUERY_REFETCH_OFF_OPTIONS } from 'lib/constants';
|
|
||||||
|
|
||||||
const fetchActuatorInfo = async () => {
|
|
||||||
const data = await fetch(
|
|
||||||
`${BASE_PARAMS.basePath}/actuator/info`,
|
|
||||||
BASE_PARAMS
|
|
||||||
).then((res) => res.json());
|
|
||||||
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function useActuatorInfo() {
|
|
||||||
return useQuery(
|
|
||||||
['actuatorInfo'],
|
|
||||||
fetchActuatorInfo,
|
|
||||||
QUERY_REFETCH_OFF_OPTIONS
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,21 +1,19 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import {
|
import { BASE_PARAMS, QUERY_REFETCH_OFF_OPTIONS } from 'lib/constants';
|
||||||
QUERY_REFETCH_OFF_OPTIONS,
|
|
||||||
GIT_REPO_LATEST_RELEASE_LINK,
|
|
||||||
} from 'lib/constants';
|
|
||||||
|
|
||||||
const fetchLatestVersion = async () => {
|
const fetchLatestVersionInfo = async () => {
|
||||||
const data = await fetch(GIT_REPO_LATEST_RELEASE_LINK).then((res) =>
|
const data = await fetch(
|
||||||
res.json()
|
`${BASE_PARAMS.basePath}/api/info`,
|
||||||
);
|
BASE_PARAMS
|
||||||
|
).then((res) => res.json());
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useLatestVersion() {
|
export function useLatestVersion() {
|
||||||
return useQuery(
|
return useQuery(
|
||||||
['latestVersion'],
|
['versionInfo'],
|
||||||
fetchLatestVersion,
|
fetchLatestVersionInfo,
|
||||||
QUERY_REFETCH_OFF_OPTIONS
|
QUERY_REFETCH_OFF_OPTIONS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue