#641 Warning that app version is outdated (#642)

* Added warning that app version is outdated

* added small fixes and tests to compareVersions
This commit is contained in:
Ilnur Yakupov 2021-07-08 12:38:12 +03:00 committed by GitHub
parent 71e1370deb
commit e5f1e47c99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 126 additions and 1 deletions

View file

@ -1,5 +1,8 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { gitCommitPath } from 'lib/paths';
import { GIT_REPO_LATEST_RELEASE_LINK } from 'lib/constants';
import compareVersions from './compareVersions';
export interface VesionProps {
tag?: string;
@ -7,14 +10,40 @@ export interface VesionProps {
}
const Version: React.FC<VesionProps> = ({ tag, commit }) => {
const [latestVersionInfo, setLatestVersionInfo] = useState({
outdated: false,
latestTag: '',
});
useEffect(() => {
if (tag) {
fetch(GIT_REPO_LATEST_RELEASE_LINK)
.then((response) => response.json())
.then((data) => {
setLatestVersionInfo({
outdated: compareVersions(tag, data.tag_name) === -1,
latestTag: data.tag_name,
});
});
}
}, [tag]);
if (!tag) {
return null;
}
const { outdated, latestTag } = latestVersionInfo;
return (
<div className="is-size-7 has-text-grey">
<span className="has-text-grey-light mr-1">Version:</span>
<span className="mr-1">{tag}</span>
{outdated && (
<span
className="icon has-text-warning"
title={`Your app version is outdated. Current latest version is ${latestTag}`}
>
<i className="fas fa-exclamation-triangle" />
</span>
)}
{commit && (
<>
<span>&#40;</span>

View file

@ -0,0 +1,69 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import compareVersions from 'components/Version/compareVersions';
describe('compareVersions function', () => {
it('single-segment versions', () => {
expect(compareVersions('10', '9')).toEqual(1);
expect(compareVersions('10', '10')).toEqual(0);
expect(compareVersions('9', '10')).toEqual(-1);
});
it('two-segment versions', () => {
expect(compareVersions('10.8', '10.4')).toEqual(1);
expect(compareVersions('10.1', '10.1')).toEqual(0);
expect(compareVersions('10.1', '10.2')).toEqual(-1);
});
it('three-segment versions', () => {
expect(compareVersions('10.1.8', '10.0.4')).toEqual(1);
expect(compareVersions('10.0.1', '10.0.1')).toEqual(0);
expect(compareVersions('10.1.1', '10.2.2')).toEqual(-1);
});
it('four-segment versions', () => {
expect(compareVersions('1.0.0.0', '1')).toEqual(0);
expect(compareVersions('1.0.0.0', '1.0')).toEqual(0);
expect(compareVersions('1.0.0.0', '1.0.0')).toEqual(0);
expect(compareVersions('1.0.0.0', '1.0.0.0')).toEqual(0);
expect(compareVersions('1.2.3.4', '1.2.3.4')).toEqual(0);
expect(compareVersions('1.2.3.4', '1.2.3.04')).toEqual(0);
expect(compareVersions('v1.2.3.4', '01.2.3.4')).toEqual(0);
expect(compareVersions('1.2.3.4', '1.2.3.5')).toEqual(-1);
expect(compareVersions('1.2.3.5', '1.2.3.4')).toEqual(1);
expect(compareVersions('1.0.0.0-alpha', '1.0.0-alpha')).toEqual(0);
expect(compareVersions('1.0.0.0-alpha', '1.0.0.0-beta')).toEqual(0);
});
it('different number of digits in same group', () => {
expect(compareVersions('11.0.10', '11.0.2')).toEqual(1);
expect(compareVersions('11.0.2', '11.0.10')).toEqual(-1);
});
it('different number of digits in different groups', () => {
expect(compareVersions('11.1.10', '11.0')).toEqual(1);
});
it('different number of digits', () => {
expect(compareVersions('1.1.1', '1')).toEqual(1);
expect(compareVersions('1.0.0', '1')).toEqual(0);
expect(compareVersions('1.0', '1.4.1')).toEqual(-1);
});
it('ignore non-numeric characters', () => {
expect(compareVersions('1.0.0-alpha.1', '1.0.0-alpha')).toEqual(0);
expect(compareVersions('1.0.0-rc', '1.0.0')).toEqual(0);
expect(compareVersions('1.0.0-alpha', '1')).toEqual(0);
expect(compareVersions('v1.0.0', '1.0.0')).toEqual(0);
});
it('returns valid result (negative test cases)', () => {
expect(compareVersions(123, 'v0.0.0')).toEqual(0);
expect(compareVersions(undefined, 'v0.0.0')).toEqual(0);
expect(compareVersions('v0.0.0', 123)).toEqual(0);
expect(compareVersions('v0.0.0', undefined)).toEqual(0);
expect(compareVersions(undefined, undefined)).toEqual(0);
});
});

View file

@ -0,0 +1,25 @@
const split = (v: string): string[] => {
const c = v.replace(/^v/, '').replace(/\+.*$/, '');
return c.split('-')[0].split('.');
};
const compareVersions = (v1: string, v2: string): number => {
try {
const s1 = split(v1);
const s2 = split(v2);
for (let i = 0; i < Math.max(s1.length, s2.length); i += 1) {
const n1 = parseInt(s1[i] || '0', 10);
const n2 = parseInt(s2[i] || '0', 10);
if (n1 > n2) return 1;
if (n2 > n1) return -1;
}
return 0;
} catch (_) {
return 0;
}
};
export default compareVersions;

View file

@ -51,5 +51,7 @@ export const BYTES_IN_GB = 1_073_741_824;
export const PER_PAGE = 25;
export const GIT_REPO_LINK = 'https://github.com/provectus/kafka-ui';
export const GIT_REPO_LATEST_RELEASE_LINK =
'https://api.github.com/repos/provectus/kafka-ui/releases/latest';
export const GIT_TAG = process.env.REACT_APP_TAG;
export const GIT_COMMIT = process.env.REACT_APP_COMMIT;