MM-63379: Fixing bot showing the local time (#30426)
* Fixing bot showing the local time * feat: Add tests for bot and non-bot user time indicator behavior * test: Update use_post_box_indicator tests with React rendering * Fixing linter checks
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d69e8b3e90
Коммит
a7c4ad832e
@@ -1,11 +1,13 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||||
|
|
||||||
import useTimePostBoxIndicator from 'components/advanced_text_editor/use_post_box_indicator';
|
import useTimePostBoxIndicator from 'components/advanced_text_editor/use_post_box_indicator';
|
||||||
|
|
||||||
import {renderHookWithContext} from 'tests/react_testing_utils';
|
import {renderHookWithContext, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||||
|
|
||||||
import type {GlobalState} from 'types/store';
|
import type {GlobalState} from 'types/store';
|
||||||
|
|
||||||
@@ -80,6 +82,18 @@ function getBaseState(): DeepPartial<GlobalState> {
|
|||||||
manualTimezone: '',
|
manualTimezone: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
current_user_id: {
|
||||||
|
id: 'current_user_id',
|
||||||
|
username: 'current_username',
|
||||||
|
nickname: 'current_nickname',
|
||||||
|
first_name: 'current_first_name',
|
||||||
|
last_name: 'current_last_name',
|
||||||
|
timezone: {
|
||||||
|
useAutomaticTimezone: 'true',
|
||||||
|
automaticTimezone: 'UTC',
|
||||||
|
manualTimezone: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
general: {
|
general: {
|
||||||
@@ -137,6 +151,7 @@ describe('useTimePostBoxIndicator', () => {
|
|||||||
expect(current.isScheduledPostEnabled).toBe(true);
|
expect(current.isScheduledPostEnabled).toBe(true);
|
||||||
expect(current.teammateTimezone.useAutomaticTimezone).toBe(true);
|
expect(current.teammateTimezone.useAutomaticTimezone).toBe(true);
|
||||||
expect(current.teammateTimezone.automaticTimezone).toBe('IST');
|
expect(current.teammateTimezone.automaticTimezone).toBe('IST');
|
||||||
|
expect(current.showRemoteUserHour).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle teammate not loaded', () => {
|
it('should handle teammate not loaded', () => {
|
||||||
@@ -151,4 +166,81 @@ describe('useTimePostBoxIndicator', () => {
|
|||||||
expect(current.teammateTimezone.useAutomaticTimezone).toBe(true);
|
expect(current.teammateTimezone.useAutomaticTimezone).toBe(true);
|
||||||
expect(current.teammateTimezone.automaticTimezone).toBe('IST');
|
expect(current.teammateTimezone.automaticTimezone).toBe('IST');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not show remote hour indicator when a user becomes a bot', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
jest.setSystemTime(new Date('2021-01-01T00:00:00Z').getTime());
|
||||||
|
const initialState = getBaseState();
|
||||||
|
const TestComponent = () => {
|
||||||
|
const {isBot, showRemoteUserHour} = useTimePostBoxIndicator('dm_channel_id');
|
||||||
|
return <div><div title='isBot'>{isBot.toString()}</div><div title='showRemoteUserHour'>{showRemoteUserHour.toString()}</div></div>;
|
||||||
|
};
|
||||||
|
const {replaceStoreState} = renderWithContext(<TestComponent/>, initialState);
|
||||||
|
|
||||||
|
// Update the state to make the teammate a bot
|
||||||
|
const updatedState = {
|
||||||
|
...initialState,
|
||||||
|
entities: {
|
||||||
|
...initialState.entities,
|
||||||
|
users: {
|
||||||
|
...initialState.entities?.users,
|
||||||
|
profiles: {
|
||||||
|
...initialState.entities?.users?.profiles,
|
||||||
|
teammate_user_id: {
|
||||||
|
...initialState.entities?.users?.profiles?.teammate_user_id,
|
||||||
|
is_bot: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rerender with updated state
|
||||||
|
replaceStoreState(updatedState);
|
||||||
|
|
||||||
|
// Now it should be a bot and remote hour indicator should be false
|
||||||
|
expect(screen.queryByTitle('isBot')?.textContent).toBe('true');
|
||||||
|
expect(screen.queryByTitle('showRemoteUserHour')?.textContent).toBe('false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should properly update when a bot becomes a regular user', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
jest.setSystemTime(new Date('2021-01-01T00:00:00Z').getTime());
|
||||||
|
const initialState = getBaseState();
|
||||||
|
const TestComponent = () => {
|
||||||
|
const {isBot, showRemoteUserHour} = useTimePostBoxIndicator('bot_dm_channel_id');
|
||||||
|
return <div><div title='isBot'>{isBot.toString()}</div><div title='showRemoteUserHour'>{showRemoteUserHour.toString()}</div></div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const {replaceStoreState} = renderWithContext(<TestComponent/>, initialState);
|
||||||
|
|
||||||
|
// Initially a bot
|
||||||
|
expect(screen.queryByTitle('isBot')?.textContent).toBe('true');
|
||||||
|
expect(screen.queryByTitle('showRemoteUserHour')?.textContent).toBe('false');
|
||||||
|
|
||||||
|
// Update the state to make the teammate not a bot
|
||||||
|
const updatedState = {
|
||||||
|
...initialState,
|
||||||
|
entities: {
|
||||||
|
...initialState.entities,
|
||||||
|
users: {
|
||||||
|
...initialState.entities?.users,
|
||||||
|
profiles: {
|
||||||
|
...initialState.entities?.users?.profiles,
|
||||||
|
bot_user_id: {
|
||||||
|
...initialState.entities?.users?.profiles?.bot_user_id,
|
||||||
|
is_bot: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rerender with updated state
|
||||||
|
replaceStoreState(updatedState);
|
||||||
|
|
||||||
|
// Now it should be a bot and remote hour indicator should be false
|
||||||
|
expect(screen.queryByTitle('isBot')?.textContent).toBe('false');
|
||||||
|
expect(screen.queryByTitle('showRemoteUserHour')?.textContent).toBe('true');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,18 +62,21 @@ function useTimePostBoxIndicator(channelId: string) {
|
|||||||
// current user timezone
|
// current user timezone
|
||||||
const userCurrentTimezone = useSelector((state: GlobalState) => getCurrentTimezone(state));
|
const userCurrentTimezone = useSelector((state: GlobalState) => getCurrentTimezone(state));
|
||||||
|
|
||||||
|
const isBot = Boolean(isDM && teammate?.is_bot);
|
||||||
|
|
||||||
// UseEffect to update the timestamp and the visibility for the time indicator
|
// UseEffect to update the timestamp and the visibility for the time indicator
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDM && teammate?.is_bot) {
|
if (isBot) {
|
||||||
// returning an empty cleanup function as we need to return a genuine cleanup
|
// returning an empty cleanup function as we need to return a genuine cleanup
|
||||||
// function at if teammate is not a bot and useEffect functions need to
|
// function at if teammate is not a bot and useEffect functions need to
|
||||||
// have consistent return types. So, we have to return a () => void function everywhere.
|
// have consistent return types. So, we have to return a () => void function everywhere.
|
||||||
|
setShowIt(false);
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTime() {
|
function updateTime() {
|
||||||
const timezone =
|
const timezone =
|
||||||
teammateTimezone.useAutomaticTimezone ? teammateTimezone.automaticTimezone : teammateTimezone.manualTimezone || 'UTC';
|
(teammateTimezone.useAutomaticTimezone ? teammateTimezone.automaticTimezone : teammateTimezone.manualTimezone) || 'UTC';
|
||||||
|
|
||||||
const teammateUserDate = DateTime.local().setZone(timezone);
|
const teammateUserDate = DateTime.local().setZone(timezone);
|
||||||
|
|
||||||
@@ -92,13 +95,12 @@ function useTimePostBoxIndicator(channelId: string) {
|
|||||||
const interval = setInterval(updateTime, MINUTE);
|
const interval = setInterval(updateTime, MINUTE);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [teammate, teammateTimezone.useAutomaticTimezone, teammateTimezone.automaticTimezone, teammateTimezone.manualTimezone, isDM]);
|
}, [teammateTimezone.useAutomaticTimezone, teammateTimezone.automaticTimezone, teammateTimezone.manualTimezone, isBot]);
|
||||||
|
|
||||||
const isScheduledPostEnabledValue = useSelector(isScheduledPostsEnabled);
|
const isScheduledPostEnabledValue = useSelector(isScheduledPostsEnabled);
|
||||||
|
|
||||||
const currentUserId = useSelector(getCurrentUserId);
|
const currentUserId = useSelector(getCurrentUserId);
|
||||||
const isSelfDM = isDM && teammateId === currentUserId;
|
const isSelfDM = isDM && teammateId === currentUserId;
|
||||||
const isBot = Boolean(isDM && teammate?.is_bot);
|
|
||||||
|
|
||||||
const showRemoteUserHour = isDM && showIt && timestamp !== 0 && !isBot;
|
const showRemoteUserHour = isDM && showIt && timestamp !== 0 && !isBot;
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user