Skip to content

Commit

Permalink
test(MaintenancePage): fix for flacky test [YTFRONT-3772]
Browse files Browse the repository at this point in the history
  • Loading branch information
ma-efremoff committed Jan 24, 2025
1 parent 24c142e commit 3b10286
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 88 deletions.
1 change: 0 additions & 1 deletion packages/ui/src/ui/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export const BLOCK_USER = GLOBAL_PREFIX + 'BLOCK_USER';
export const BAN_USER = GLOBAL_PREFIX + 'BAN_USER';
export const INC_NAV_BLOCKER_COUNTER = GLOBAL_PREFIX + 'INC_NAV_BLOCKER_COUNTER';
export const DEC_NAV_BLOCKER_COUNTER = GLOBAL_PREFIX + 'DEC_NAV_BLOCKER_COUNTER';
export const SET_MAINTENANCE_PAGE_EVENT = GLOBAL_PREFIX + 'SET_MAINTENANCE_PAGE_EVENT';
export const SPLIT_SCREEN = GLOBAL_PREFIX + 'SPLIT_SCREEN';
export const MERGE_SCREEN = GLOBAL_PREFIX + 'MERGE_SCREEN';
export const INIT_CLUSTER_PARAMS = createActionTypes(GLOBAL_PREFIX + 'INIT_CLUSTER_PARAMS');
Expand Down
16 changes: 3 additions & 13 deletions packages/ui/src/ui/containers/ClusterPage/ClusterPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {PageHeadByCluster} from '../../components/PageHead/PageHead';

import FlexSplitPane from '../../components/FlexSplitPane/FlexSplitPane';
import ErrorBlock from '../../components/Error/Error';
import HandleMaintenance from '../../containers/MaintenancePage/HandleMaintenance';
import {HandleMaintenance} from '../../containers/MaintenancePage/HandleMaintenance';
import PreloadError from '../../containers/PreloadError/PreloadError';

import {LOADING_STATUS, Page, SPLIT_PANE_ID} from '../../constants/index';
Expand Down Expand Up @@ -68,7 +68,6 @@ class ClusterPage extends Component {
clusterPagePaneSizes: PropTypes.array,
login: PropTypes.string,
queriesPageAllowed: PropTypes.bool,
maintenancePageEvent: PropTypes.object,
startingPage: PropTypes.string.isRequired,
isLoaded: PropTypes.bool.isRequired,
hasError: PropTypes.bool.isRequired,
Expand Down Expand Up @@ -317,16 +316,8 @@ class ClusterPage extends Component {
}

function mapStateToProps(state) {
const {
login,
maintenancePageEvent,
splitScreen,
loadState,
error,
paramsCluster,
paramsLoading,
paramsError,
} = state.global;
const {login, splitScreen, loadState, error, paramsCluster, paramsLoading, paramsError} =
state.global;

const clusters = state.clustersMenu.clusters;

Expand All @@ -338,7 +329,6 @@ function mapStateToProps(state) {
paramsError,
login,
splitScreen,
maintenancePageEvent,
clusterPagePaneSizes: getClusterPagePaneSizes(state),
startingPage: getStartingPage(state),
paramsCluster,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import './ClusterPageHeader.scss';
import {ClusterPicker} from './ClusterPicker';
import {HeadSpacer} from './HeadSpacer';
import {getClusterConfigByName} from '../../store/selectors/global';
import HandleMaintenance from '../../containers/MaintenancePage/HandleMaintenance';
import {HandleMaintenance} from '../../containers/MaintenancePage/HandleMaintenance';

const block = cn('cluster-page-header');

Expand All @@ -16,7 +16,7 @@ function ClusterPageHeader({cluster}: {cluster: string}) {
<div className={block()}>
<ClusterPicker cluster={cluster} clusterConfig={clusterConfig} />
<HeadSpacer />
<HandleMaintenance cluster={cluster} maintenanceContent={null}>
<HandleMaintenance cluster={cluster} emptyMaintenance>
<TopRowContent />
</HandleMaintenance>
</div>
Expand Down
62 changes: 24 additions & 38 deletions packages/ui/src/ui/containers/MaintenancePage/HandleMaintenance.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,37 @@
import React from 'react';
import {ConnectedProps, connect} from 'react-redux';
import {useSelector} from 'react-redux';

import {MaintenancePage} from '../../containers/MaintenancePage/MaintenancePage';
import {RootState} from '../../store/reducers';
import {isMaintenanceIgnored, setMaintenanceIgnored} from '../../utils/maintenance';
import {getMaintenanceEvent} from '../../store/selectors/global/maintenance';

type Props = {
cluster: string;
children: React.ReactNode;
maintenanceContent?: React.ReactNode;
emptyMaintenance?: boolean;
};

type ReduxProps = ConnectedProps<typeof connector>;

class HandleMaintenance extends React.Component<Props & ReduxProps> {
render() {
const {cluster, maintenancePageEvent, maintenanceContent, children} = this.props;

if (maintenancePageEvent) {
const isIgnored = isMaintenanceIgnored(cluster);

if (!isIgnored) {
return maintenanceContent !== undefined ? (
maintenanceContent
) : (
<MaintenancePage
cluster={cluster}
maintenancePageEvent={maintenancePageEvent}
onProceed={() => {
setMaintenanceIgnored(cluster);
this.forceUpdate();
}}
/>
);
}
export function HandleMaintenance({cluster, children, emptyMaintenance}: Props) {
const [c, forceUpdate] = React.useState(0);

const maintenancePageEvent = useSelector(getMaintenanceEvent);

if (maintenancePageEvent) {
const isIgnored = isMaintenanceIgnored(cluster);

if (!isIgnored) {
return emptyMaintenance ? null : (
<MaintenancePage
cluster={cluster}
maintenancePageEvent={maintenancePageEvent}
onProceed={() => {
setMaintenanceIgnored(cluster);
forceUpdate(c + 1);
}}
/>
);
}

return children;
}
}

const mapStateToProps = (state: RootState) => {
const {maintenancePageEvent, eventsFirstUpdate} = state.global;

return {maintenancePageEvent, eventsFirstUpdate};
};

const connector = connect(mapStateToProps);

export default connector(HandleMaintenance);
return children;
}
7 changes: 3 additions & 4 deletions packages/ui/src/ui/store/actions/global/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
GLOBAL_SET_THEME,
INC_NAV_BLOCKER_COUNTER,
MERGE_SCREEN,
SET_MAINTENANCE_PAGE_EVENT,
SPLIT_SCREEN,
UPDATE_TITLE,
} from '../../../constants/index';
Expand Down Expand Up @@ -288,10 +287,10 @@ export function removeNavigationBlocker() {
};
}

export function setMaintenancePageEvent(events: Array<unknown>, isFirstUpdate: boolean) {
export function setOngoingClusterEvents(cluster: string, events: Array<unknown>) {
return {
type: SET_MAINTENANCE_PAGE_EVENT,
data: {events, isFirstUpdate},
type: GLOBAL_PARTIAL,
data: {ongoingEvents: {events, cluster}},
};
}

Expand Down
31 changes: 1 addition & 30 deletions packages/ui/src/ui/store/reducers/global/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import filter_ from 'lodash/filter';
import find_ from 'lodash/find';
import sortBy_ from 'lodash/sortBy';

import {LOCATION_POP} from 'redux-location-state/lib/constants';
Expand All @@ -14,7 +13,6 @@ import {
LOADING_STATUS,
MERGE_SCREEN,
PRELOAD_ERROR,
SET_MAINTENANCE_PAGE_EVENT,
SPLIT_SCREEN,
UPDATE_CLUSTER,
UPDATE_TITLE,
Expand Down Expand Up @@ -46,9 +44,7 @@ const initialState = {
// scrollOffset: 0,
blocked: false, // user may become automatically temporarily banned
banned: false, // user may be banned by administrator
maintenancePageEvent: null,
ongoingPageEvents: null,
eventsFirstUpdate: false,
ongoingEvents: {cluster: '', events: []},

loadState: LOADING_STATUS.UNINITIALIZED,
error: EMPTY_OBJECT,
Expand Down Expand Up @@ -168,22 +164,9 @@ export default (state = initialState, action) => {
case BAN_USER:
return {...state, banned: true};

case SET_MAINTENANCE_PAGE_EVENT: {
const {events, isFirstUpdate} = action.data;
const maintenancePageEvent = getNotificationWithMaintenance(events);

return {
...state,
maintenancePageEvent,
ongoingPageEvents: events,
eventsFirstUpdate: isFirstUpdate,
};
}

case UPDATE_CLUSTER.REQUEST:
return {
...state,
maintenancePageEvent: null,
loadState: LOADING_STATUS.LOADING,
};

Expand Down Expand Up @@ -240,15 +223,3 @@ export default (state = initialState, action) => {
return state;
}
};

function getNotificationWithMaintenance(notifications) {
return find_(notifications, (notification) => {
try {
const meta = JSON.parse(notification.meta);
return meta && meta.show_maintenance_page;
} catch (err) {
console.error('Failed to parse notification meta', err);
return null;
}
});
}
13 changes: 13 additions & 0 deletions packages/ui/src/ui/store/reducers/index.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,22 @@ export type RootState = Omit<ReturnType<ReturnType<typeof makeRootReducer>>, 'gl
allowedExperimentalPages?: Array<string>;
ytAuthCluster?: string;
defaultPoolTree?: string;

ongoingEvents?: {cluster?: string; events?: Array<MaintenanceEvent>};
};
};

export type MaintenanceEvent = {
type: string;
startTime: string;
finishTime: string;
severity: string;
title: string;
description: string;
createdBy: string;
meta?: string;
};

function registerReducersAndUrlMapping(
item: Pick<UIFactoryClusterPageInfo, 'reducers' | 'urlMapping'>,
) {
Expand Down
24 changes: 24 additions & 0 deletions packages/ui/src/ui/store/selectors/global/maintenance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {createSelector} from 'reselect';
import {RootState} from '../../../store/reducers';
import {getCluster} from './cluster';

const getOngoingEvents = (state: RootState) => state.global.ongoingEvents;

export const getMaintenanceEvent = createSelector(
[getCluster, getOngoingEvents],
(cluster, ongoing) => {
if (!ongoing?.events?.length || cluster !== ongoing.cluster) {
return undefined;
}

return ongoing.events.find((item) => {
try {
const meta = JSON.parse(item.meta!);
return meta && meta.show_maintenance_page;
} catch (err) {
console.error('Failed to parse notification meta', err);
return null;
}
});
},
);

0 comments on commit 3b10286

Please sign in to comment.