mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-06-27 04:22:05 +00:00
fix(ui): version link and fetch logic with 1 hour wait time (#21932)
* fix(ui): version link and fetch logic with 1 hour wait time * fix tests * fix test
This commit is contained in:
parent
693292406d
commit
1e50fc1376
@ -124,7 +124,6 @@
|
||||
.slick-active {
|
||||
button {
|
||||
background-color: @primary-color;
|
||||
width: inherit;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,10 @@
|
||||
*/
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { ONE_HOUR_MS } from '../../constants/constants';
|
||||
import {
|
||||
LAST_VERSION_FETCH_TIME_KEY,
|
||||
ONE_HOUR_MS,
|
||||
} from '../../constants/constants';
|
||||
import { HELP_ITEMS_ENUM } from '../../constants/Navbar.constants';
|
||||
import { getVersion } from '../../rest/miscAPI';
|
||||
import { getHelpDropdownItems } from '../../utils/NavbarUtils';
|
||||
@ -177,13 +180,13 @@ describe('Test NavBar Component', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// --- Additional tests for fetchOMVersion one hour threshold ---
|
||||
describe('fetchOMVersion one hour threshold', () => {
|
||||
// --- Tests for handleDocumentVisibilityChange one hour threshold ---
|
||||
describe('handleDocumentVisibilityChange one hour threshold', () => {
|
||||
const OLD_DATE_NOW = Date.now;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
jest.clearAllMocks();
|
||||
global.Date.now = jest.fn();
|
||||
});
|
||||
|
||||
@ -191,7 +194,7 @@ describe('fetchOMVersion one hour threshold', () => {
|
||||
global.Date.now = OLD_DATE_NOW;
|
||||
});
|
||||
|
||||
it('should NOT call getVersion if less than one hour since last fetch', async () => {
|
||||
it('should NOT call getVersion on window focus if less than one hour since last fetch', async () => {
|
||||
const now = 2000000;
|
||||
const lastFetch = now - (ONE_HOUR_MS - 1000); // less than 1 hour ago
|
||||
mockGetItem.mockReturnValue(String(lastFetch));
|
||||
@ -200,26 +203,63 @@ describe('fetchOMVersion one hour threshold', () => {
|
||||
render(<NavBarComponent />);
|
||||
await screen.findByTestId('global-search-bar');
|
||||
|
||||
// Clear the initial getVersion call from mount
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Simulate window focus event
|
||||
await act(async () => {
|
||||
window.dispatchEvent(new Event('focus'));
|
||||
});
|
||||
|
||||
expect(getVersion).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call getVersion and setItem if more than one hour since last fetch', async () => {
|
||||
it('should call getVersion and setItem on window focus if more than one hour since last fetch', async () => {
|
||||
const now = 3000000;
|
||||
const lastFetch = now - (ONE_HOUR_MS + 1000); // more than 1 hour ago
|
||||
mockGetItem.mockReturnValue(String(lastFetch));
|
||||
(global.Date.now as jest.Mock).mockReturnValue(now);
|
||||
|
||||
render(<NavBarComponent />);
|
||||
await Promise.resolve();
|
||||
await screen.findByTestId('global-search-bar');
|
||||
|
||||
// Clear the initial getVersion call from mount
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Simulate window focus event
|
||||
await act(async () => {
|
||||
expect(getVersion).toHaveBeenCalled();
|
||||
window.dispatchEvent(new Event('focus'));
|
||||
});
|
||||
|
||||
expect(getVersion).toHaveBeenCalled();
|
||||
expect(mockSetItem).toHaveBeenCalledWith(
|
||||
'versionFetchTime',
|
||||
LAST_VERSION_FETCH_TIME_KEY,
|
||||
'3000000',
|
||||
expect.objectContaining({ expires: expect.any(Date) })
|
||||
);
|
||||
});
|
||||
|
||||
it('should call getVersion on window focus if no previous fetch time exists', async () => {
|
||||
const now = 4000000;
|
||||
mockGetItem.mockReturnValue(null); // No previous fetch time
|
||||
(global.Date.now as jest.Mock).mockReturnValue(now);
|
||||
|
||||
render(<NavBarComponent />);
|
||||
await screen.findByTestId('global-search-bar');
|
||||
|
||||
// Clear the initial getVersion call from mount
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Simulate window focus event
|
||||
await act(async () => {
|
||||
window.dispatchEvent(new Event('focus'));
|
||||
});
|
||||
|
||||
expect(getVersion).toHaveBeenCalled();
|
||||
expect(mockSetItem).toHaveBeenCalledWith(
|
||||
LAST_VERSION_FETCH_TIME_KEY,
|
||||
'4000000',
|
||||
expect.objectContaining({ expires: expect.any(Date) })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -45,10 +45,10 @@ import { ReactComponent as SidebarCollapsedIcon } from '../../assets/svg/ic-side
|
||||
import { ReactComponent as SidebarExpandedIcon } from '../../assets/svg/ic-sidebar-expanded.svg';
|
||||
import {
|
||||
DEFAULT_DOMAIN_VALUE,
|
||||
LAST_VERSION_FETCH_TIME_KEY,
|
||||
NOTIFICATION_READ_TIMER,
|
||||
ONE_HOUR_MS,
|
||||
SOCKET_EVENTS,
|
||||
VERSION_FETCH_TIME_KEY,
|
||||
} from '../../constants/constants';
|
||||
import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.constants';
|
||||
import { HELP_ITEMS_ENUM } from '../../constants/Navbar.constants';
|
||||
@ -130,22 +130,16 @@ const NavBar = () => {
|
||||
} = useCurrentUserPreferences();
|
||||
|
||||
const fetchOMVersion = async () => {
|
||||
// If version fetch happens within an hour, skip fetching
|
||||
const lastFetchTime = cookieStorage.getItem(VERSION_FETCH_TIME_KEY);
|
||||
const now = Date.now();
|
||||
|
||||
if (lastFetchTime && now - Number(lastFetchTime) < ONE_HOUR_MS) {
|
||||
// Less than an hour since last fetch, skip fetching
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getVersion();
|
||||
setVersion(res.version);
|
||||
// Set/update the cookie with current time, expires in 1 hour
|
||||
cookieStorage.setItem(VERSION_FETCH_TIME_KEY, String(now), {
|
||||
expires: new Date(now + ONE_HOUR_MS),
|
||||
|
||||
const now = Date.now();
|
||||
// Update the cache timestamp
|
||||
cookieStorage.setItem(LAST_VERSION_FETCH_TIME_KEY, String(now), {
|
||||
expires: new Date(Date.now() + ONE_HOUR_MS),
|
||||
});
|
||||
|
||||
setVersion(res.version);
|
||||
} catch (err) {
|
||||
showErrorToast(
|
||||
err as AxiosError,
|
||||
@ -325,7 +319,27 @@ const NavBar = () => {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we need to fetch based on cache timing
|
||||
// This is to block the API call for 1 hour
|
||||
const lastFetchTime = cookieStorage.getItem(LAST_VERSION_FETCH_TIME_KEY);
|
||||
const now = Date.now();
|
||||
|
||||
if (lastFetchTime) {
|
||||
const timeSinceLastFetch = now - parseInt(lastFetchTime);
|
||||
if (timeSinceLastFetch < ONE_HOUR_MS) {
|
||||
// Less than 1 hour since last fetch, skip API call
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const newVersion = await getVersion();
|
||||
|
||||
// Update the cache timestamp
|
||||
cookieStorage.setItem(LAST_VERSION_FETCH_TIME_KEY, String(now), {
|
||||
expires: new Date(Date.now() + ONE_HOUR_MS),
|
||||
});
|
||||
|
||||
// Compare version only if version is set previously to have fair comparison
|
||||
if (version && version !== newVersion.version) {
|
||||
setShowVersionMissMatchAlert(true);
|
||||
|
@ -21,7 +21,7 @@ import documentationLinksClassBase from '../utils/DocumentationLinksClassBase';
|
||||
|
||||
import i18n from '../utils/i18next/LocalUtil';
|
||||
import { ROUTES } from './constants';
|
||||
import { URL_GITHUB_REPO, URL_JOIN_SLACK } from './URL.constants';
|
||||
import { URL_JOIN_SLACK, URL_OM_RELEASE_UPDATES } from './URL.constants';
|
||||
|
||||
export enum HELP_ITEMS_ENUM {
|
||||
TOUR = 'tour',
|
||||
@ -80,7 +80,7 @@ export const HELP_ITEMS = [
|
||||
key: HELP_ITEMS_ENUM.VERSION,
|
||||
label: i18n.t('label.version'),
|
||||
icon: IconVersionBlack,
|
||||
link: URL_GITHUB_REPO,
|
||||
link: URL_OM_RELEASE_UPDATES,
|
||||
isExternal: true,
|
||||
},
|
||||
];
|
||||
|
@ -14,3 +14,6 @@
|
||||
export const URL_JOIN_SLACK = 'https://slack.open-metadata.org';
|
||||
export const URL_OPEN_METADATA_DOCS = 'https://docs.open-metadata.org/';
|
||||
export const URL_GITHUB_REPO = 'https://github.com/open-metadata/OpenMetadata';
|
||||
|
||||
export const URL_OM_RELEASE_UPDATES =
|
||||
'https://open-metadata.org/product-updates#{{currentVersion}}';
|
||||
|
@ -65,6 +65,8 @@ export const MAX_CHAR_LIMIT_ENTITY_SUMMARY = 130;
|
||||
export const TEST_CASE_FEED_GRAPH_HEIGHT = 250;
|
||||
export const ONE_MINUTE_IN_MILLISECOND = 60000;
|
||||
export const TWO_MINUTE_IN_MILLISECOND = 120000;
|
||||
export const ONE_HOUR_MS = 3600000; // 1 hour in milliseconds
|
||||
export const LAST_VERSION_FETCH_TIME_KEY = 'versionFetchTime';
|
||||
export const LOCALSTORAGE_RECENTLY_VIEWED = `recentlyViewedData_${COOKIE_VERSION}`;
|
||||
export const LOCALSTORAGE_RECENTLY_SEARCHED = `recentlySearchedData_${COOKIE_VERSION}`;
|
||||
export const REDIRECT_PATHNAME = 'redirectUrlPath';
|
||||
@ -432,6 +434,3 @@ export const MAX_VISIBLE_OWNERS_FOR_FEED_TAB = 4;
|
||||
export const MAX_VISIBLE_OWNERS_FOR_FEED_CARD = 2;
|
||||
|
||||
export const BREADCRUMB_SEPARATOR = '/';
|
||||
|
||||
export const VERSION_FETCH_TIME_KEY = 'versionFetchTime';
|
||||
export const ONE_HOUR_MS = 60 * 60 * 1000;
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
import { ROUTES } from '../constants/constants';
|
||||
import {
|
||||
URL_GITHUB_REPO,
|
||||
URL_JOIN_SLACK,
|
||||
URL_OM_RELEASE_UPDATES,
|
||||
URL_OPEN_METADATA_DOCS,
|
||||
} from '../constants/URL.constants';
|
||||
import navbarUtilClassBase from './NavbarUtilClassBase';
|
||||
@ -28,7 +28,7 @@ describe('NavbarUtilClassBase', () => {
|
||||
expect(stringifyResult).toContain(URL_OPEN_METADATA_DOCS);
|
||||
expect(stringifyResult).toContain(ROUTES.SWAGGER);
|
||||
expect(stringifyResult).toContain(URL_JOIN_SLACK);
|
||||
expect(stringifyResult).toContain(URL_GITHUB_REPO);
|
||||
expect(stringifyResult).toContain(URL_OM_RELEASE_UPDATES);
|
||||
expect(stringifyResult).toContain('label.tour');
|
||||
expect(stringifyResult).toContain('label.doc-plural');
|
||||
expect(stringifyResult).toContain('label.api-uppercase');
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
import { ROUTES } from '../constants/constants';
|
||||
import { HELP_ITEMS_ENUM } from '../constants/Navbar.constants';
|
||||
import { URL_GITHUB_REPO } from '../constants/URL.constants';
|
||||
import { URL_OM_RELEASE_UPDATES } from '../constants/URL.constants';
|
||||
import { getHelpDropdownItems } from './NavbarUtils';
|
||||
|
||||
describe('NavbarUtils test', () => {
|
||||
@ -30,7 +30,9 @@ describe('NavbarUtils test', () => {
|
||||
// Test external link
|
||||
const externalLink = helpDropdownItems[5].label.props.href;
|
||||
|
||||
expect(externalLink).toBe(URL_GITHUB_REPO);
|
||||
expect(externalLink).toBe(
|
||||
URL_OM_RELEASE_UPDATES.replace('{{currentVersion}}', version)
|
||||
);
|
||||
expect(helpDropdownItems[5].label.props.target).toBe('_blank');
|
||||
expect(helpDropdownItems[5].label.props.rel).toBe('noreferrer');
|
||||
|
||||
|
@ -56,7 +56,7 @@ const getHelpDropdownLabel = (item: SupportItem, version?: string) => {
|
||||
return (
|
||||
<a
|
||||
className="no-underline"
|
||||
href={item.link}
|
||||
href={item.link?.replace('{{currentVersion}}', version ?? '')}
|
||||
rel="noreferrer"
|
||||
target="_blank">
|
||||
{getHelpDropdownLabelContentRenderer(item, version)}
|
||||
|
Loading…
x
Reference in New Issue
Block a user