From a7c4ad832e0a2f7690fad967d915a18150b44591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Mon, 24 Mar 2025 13:02:21 +0100 Subject: [PATCH] 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 --- .../use_post_box_indicator.test.tsx | 94 ++++++++++++++++++- .../use_post_box_indicator.tsx | 10 +- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.test.tsx b/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.test.tsx index 4fd02c3b64..6db93503c0 100644 --- a/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.test.tsx +++ b/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.test.tsx @@ -1,11 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import React from 'react'; + import type {DeepPartial} from '@mattermost/types/utilities'; 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'; @@ -80,6 +82,18 @@ function getBaseState(): DeepPartial { 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: { @@ -137,6 +151,7 @@ describe('useTimePostBoxIndicator', () => { expect(current.isScheduledPostEnabled).toBe(true); expect(current.teammateTimezone.useAutomaticTimezone).toBe(true); expect(current.teammateTimezone.automaticTimezone).toBe('IST'); + expect(current.showRemoteUserHour).toBe(false); }); it('should handle teammate not loaded', () => { @@ -151,4 +166,81 @@ describe('useTimePostBoxIndicator', () => { expect(current.teammateTimezone.useAutomaticTimezone).toBe(true); 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
{isBot.toString()}
{showRemoteUserHour.toString()}
; + }; + const {replaceStoreState} = renderWithContext(, 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
{isBot.toString()}
{showRemoteUserHour.toString()}
; + }; + + const {replaceStoreState} = renderWithContext(, 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'); + }); }); diff --git a/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.tsx b/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.tsx index e87a093dee..e70bf9f611 100644 --- a/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.tsx +++ b/webapp/channels/src/components/advanced_text_editor/use_post_box_indicator.tsx @@ -62,18 +62,21 @@ function useTimePostBoxIndicator(channelId: string) { // current user timezone 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(() => { - if (isDM && teammate?.is_bot) { + if (isBot) { // 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 // have consistent return types. So, we have to return a () => void function everywhere. + setShowIt(false); return () => {}; } function updateTime() { const timezone = - teammateTimezone.useAutomaticTimezone ? teammateTimezone.automaticTimezone : teammateTimezone.manualTimezone || 'UTC'; + (teammateTimezone.useAutomaticTimezone ? teammateTimezone.automaticTimezone : teammateTimezone.manualTimezone) || 'UTC'; const teammateUserDate = DateTime.local().setZone(timezone); @@ -92,13 +95,12 @@ function useTimePostBoxIndicator(channelId: string) { const interval = setInterval(updateTime, MINUTE); return () => clearInterval(interval); - }, [teammate, teammateTimezone.useAutomaticTimezone, teammateTimezone.automaticTimezone, teammateTimezone.manualTimezone, isDM]); + }, [teammateTimezone.useAutomaticTimezone, teammateTimezone.automaticTimezone, teammateTimezone.manualTimezone, isBot]); const isScheduledPostEnabledValue = useSelector(isScheduledPostsEnabled); const currentUserId = useSelector(getCurrentUserId); const isSelfDM = isDM && teammateId === currentUserId; - const isBot = Boolean(isDM && teammate?.is_bot); const showRemoteUserHour = isDM && showIt && timestamp !== 0 && !isBot;