diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index cf0c6368090a..86f634120491 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -1335,6 +1335,7 @@ const CONST = {
REMOVE_FROM_ROOM: 'REMOVEFROMROOM',
LEAVE_ROOM: 'LEAVEROOM',
UPDATE_ROOM_DESCRIPTION: 'UPDATEROOMDESCRIPTION',
+ UPDATE_ROOM_AVATAR: 'UPDATEROOMAVATAR',
},
REJECTEDTRANSACTION_THREAD: 'REJECTEDTRANSACTION_THREAD',
REJECTED_TRANSACTION_MARKASRESOLVED: 'REJECTEDTRANSACTIONMARKASRESOLVED',
diff --git a/src/components/AvatarButtonWithIcon.tsx b/src/components/AvatarButtonWithIcon.tsx
index d2800733d6ca..c99161469915 100644
--- a/src/components/AvatarButtonWithIcon.tsx
+++ b/src/components/AvatarButtonWithIcon.tsx
@@ -61,6 +61,9 @@ type AvatarButtonWithIconProps = {
/** Optionally override the default "Edit" icon */
editIcon?: IconAsset;
+
+ /** The name associated with avatar */
+ name?: string;
};
/**
@@ -82,6 +85,7 @@ function AvatarButtonWithIcon({
disabled = false,
editIcon = Expensicons.Pencil,
anchorRef,
+ name = '',
}: AvatarButtonWithIconProps) {
const theme = useTheme();
const styles = useThemeStyles();
@@ -110,6 +114,7 @@ function AvatarButtonWithIcon({
fallbackIcon={fallbackIcon}
size={size}
type={type}
+ name={name}
/>
) : (
diff --git a/src/components/AvatarWithImagePicker.tsx b/src/components/AvatarWithImagePicker.tsx
index 45bf6422ac7b..60914e47fdf1 100644
--- a/src/components/AvatarWithImagePicker.tsx
+++ b/src/components/AvatarWithImagePicker.tsx
@@ -69,6 +69,9 @@ type AvatarWithImagePickerProps = Omit
;
+ participants: number[];
};
-function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
+function RoomHeaderAvatars({icons, report, policy, participants}: RoomHeaderAvatarsProps) {
const navigateToAvatarPage = (icon: Icon) => {
if (icon.type === CONST.ICON_TYPE_WORKSPACE && icon.id) {
- Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(reportID, icon.id.toString()));
+ Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report?.reportID, icon.id.toString()));
return;
}
@@ -30,6 +38,8 @@ function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
+ const currentUserAccountID = getCurrentUserAccountID();
+ const canEditRoomAvatar = isUserCreatedPolicyRoom(report) && participants.includes(currentUserAccountID) && !!policy && policy.role !== CONST.POLICY.ROLE.AUDITOR;
if (!icons.length) {
return null;
@@ -42,6 +52,31 @@ function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
return;
}
+ if (canEditRoomAvatar) {
+ return (
+ Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report.reportID))}
+ onImageRemoved={() => updatePolicyRoomAvatar(report.reportID)}
+ onImageSelected={(file) => updatePolicyRoomAvatar(report.reportID, file)}
+ editIcon={Expensicons.Camera}
+ editIconStyle={styles.smallEditIconAccount}
+ pendingAction={report.pendingFields?.avatar}
+ errors={report.errorFields?.avatar ?? null}
+ errorRowStyles={styles.mt6}
+ onErrorClose={() => clearAvatarErrors(report.reportID)}
+ style={[styles.w100, styles.mb3, styles.alignItemsStart, styles.sectionMenuItemTopDescription]}
+ type={icon.type}
+ editorMaskImage={Expensicons.ImageCropSquareMask}
+ name={icon.name}
+ />
+ );
+ }
+
return (
${message}`, type: 'COMMENT'}];
}
+ if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_AVATAR)) {
+ const message = getRoomAvatarUpdatedMessage(action);
+ return [{text: message, html: `${message}`, type: 'COMMENT'}];
+ }
+
if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_DESCRIPTION)) {
const message = getWorkspaceDescriptionUpdatedMessage(action);
return [{text: message, html: `${message}`, type: 'COMMENT'}];
@@ -2262,6 +2267,17 @@ function getUpdateRoomDescriptionMessage(reportAction: ReportAction): string {
return translateLocal('roomChangeLog.clearRoomDescription');
}
+function getRoomAvatarUpdatedMessage(reportAction: ReportAction): string {
+ const originalMessage = getOriginalMessage(reportAction) as OriginalMessageChangeLog;
+ if (originalMessage?.avatarURL) {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ return translateLocal('roomChangeLog.changedRoomAvatar');
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ return translateLocal('roomChangeLog.removedRoomAvatar');
+}
+
function getRetractedMessage(): string {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return translateLocal('iou.retracted');
@@ -3406,6 +3422,7 @@ export {
getExportIntegrationLastMessageText,
getExportIntegrationMessageHTML,
getUpdateRoomDescriptionMessage,
+ getRoomAvatarUpdatedMessage,
didMessageMentionCurrentUser,
getPolicyChangeLogAddEmployeeMessage,
getPolicyChangeLogUpdateEmployee,
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index a6c1449c6b73..d5583e4ede62 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -570,6 +570,11 @@ type OptimisticRoomDescriptionUpdatedReportAction = Pick<
'actorAccountID' | 'created' | 'message' | 'person' | 'reportActionID' | 'pendingAction' | 'actionName' | 'originalMessage'
>;
+type OptimisticRoomAvatarUpdatedReportAction = Pick<
+ ReportAction,
+ 'actorAccountID' | 'created' | 'message' | 'person' | 'reportActionID' | 'pendingAction' | 'actionName' | 'originalMessage'
+>;
+
type OptimisticChatReport = Pick<
Report,
| 'type'
@@ -1004,6 +1009,7 @@ Onyx.connect({
return acc;
}
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
handlePreexistingReport(report);
});
@@ -3530,6 +3536,26 @@ function getIconsForInvoiceReport(
return icons;
}
+/**
+ * Helper function to get the icons for a user-created policy room. Only to be used in getIcons().
+ */
+function getIconsForUserCreatedPolicyRoom(report: OnyxInputOrEntry, policy: OnyxInputOrEntry): Icon[] {
+ if (!report) {
+ return [];
+ }
+ if (report?.avatarUrl) {
+ return [
+ {
+ source: report.avatarUrl,
+ type: CONST.ICON_TYPE_WORKSPACE,
+ name: getPolicyName({report, policy}),
+ id: report?.policyID,
+ },
+ ];
+ }
+ return [getWorkspaceIcon(report, policy)];
+}
+
/**
* Returns the appropriate icons for the given chat report using the stored personalDetails.
* The Avatar sources can be URLs or Icon components according to the chat type.
@@ -3566,6 +3592,9 @@ function getIcons(
if (isDomainRoom(report)) {
return getIconsForDomainRoom(report);
}
+ if (isUserCreatedPolicyRoom(report)) {
+ return getIconsForUserCreatedPolicyRoom(report, policy);
+ }
if (isAdminRoom(report) || isAnnounceRoom(report) || isChatRoom(report) || (isArchivedNonExpenseReport(report, isReportArchived) && !chatIncludesConcierge(report))) {
return getIconsForPolicyRoom(report, personalDetails, policy, invoiceReceiverPolicy);
}
@@ -7685,6 +7714,38 @@ function buildOptimisticRoomDescriptionUpdatedReportAction(description: string):
};
}
+/**
+ * Returns the necessary reportAction onyx data to indicate that the room avatar has been updated
+ */
+function buildOptimisticRoomAvatarUpdatedReportAction(avatarURL: string): OptimisticRoomAvatarUpdatedReportAction {
+ const now = DateUtils.getDBTime();
+ return {
+ reportActionID: rand64(),
+ actionName: CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_AVATAR,
+ pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
+ actorAccountID: currentUserAccountID,
+ message: [
+ {
+ type: CONST.REPORT.MESSAGE.TYPE.COMMENT,
+ text: avatarURL ? `changed the room avatar` : 'removed the room avatar',
+ html: avatarURL ? `changed the room avatar` : 'removed the room avatar',
+ },
+ ],
+ person: [
+ {
+ type: CONST.REPORT.MESSAGE.TYPE.TEXT,
+ style: 'strong',
+ text: getCurrentUserDisplayNameOrEmail(),
+ },
+ ],
+ originalMessage: {
+ avatarURL,
+ lastModified: now,
+ },
+ created: now,
+ };
+}
+
/**
* Returns the necessary reportAction onyx data to indicate that the transaction has been put on hold optimistically
* @param [created] - Action created time
@@ -12223,6 +12284,7 @@ export {
buildOptimisticChangePolicyReportAction,
buildOptimisticRenamedRoomReportAction,
buildOptimisticRoomDescriptionUpdatedReportAction,
+ buildOptimisticRoomAvatarUpdatedReportAction,
buildOptimisticReportPreview,
buildOptimisticActionableTrackExpenseWhisper,
buildOptimisticSubmittedReportAction,
diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts
index 2ffe5bf060cd..44198e6fecc6 100644
--- a/src/libs/SidebarUtils.ts
+++ b/src/libs/SidebarUtils.ts
@@ -52,6 +52,7 @@ import {
getReportAction,
getReportActionMessageText,
getRetractedMessage,
+ getRoomAvatarUpdatedMessage,
getTagListNameUpdatedMessage,
getTravelUpdateMessage,
getUpdatedApprovalRuleMessage,
@@ -896,6 +897,8 @@ function getOptionData({
result.alternateText = getMessageOfOldDotReportAction(lastAction);
} else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_DESCRIPTION) {
result.alternateText = getUpdateRoomDescriptionMessage(lastAction);
+ } else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_AVATAR) {
+ result.alternateText = getRoomAvatarUpdatedMessage(lastAction);
} else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.ADD_EMPLOYEE) {
result.alternateText = getPolicyChangeLogAddEmployeeMessage(lastAction);
} else if (lastAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_EMPLOYEE) {
diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts
index 4608f1257d18..0414953ff417 100644
--- a/src/libs/actions/Report.ts
+++ b/src/libs/actions/Report.ts
@@ -54,6 +54,7 @@ import type {
UpdateReportNotificationPreferenceParams,
UpdateReportPrivateNoteParams,
UpdateReportWriteCapabilityParams,
+ UpdateRoomAvatarParams,
UpdateRoomDescriptionParams,
} from '@libs/API/parameters';
import type ExportReportCSVParams from '@libs/API/parameters/ExportReportCSVParams';
@@ -111,6 +112,7 @@ import {
buildOptimisticMovedReportAction,
buildOptimisticRenamedRoomReportAction,
buildOptimisticReportPreview,
+ buildOptimisticRoomAvatarUpdatedReportAction,
buildOptimisticRoomDescriptionUpdatedReportAction,
buildOptimisticSelfDMReport,
buildOptimisticUnHoldReportAction,
@@ -924,7 +926,15 @@ function updateChatName(reportID: string, reportName: string, type: typeof CONST
API.write(command, parameters, {optimisticData, successData, failureData});
}
-function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageManipulatorResult) {
+/**
+ * Helper function to build optimistic, success, and failure Onyx updates
+ * when updating or removing a report's avatar.
+ *
+ * @param reportID - The report ID of the policy room.
+ * @param [file] - (Optional) The selected image file to update the avatar with.
+ * If not provided, the existing avatar will be removed.
+ */
+function buildUpdateReportAvatarOnyxData(reportID: string, file?: File | CustomRNImageManipulatorResult) {
// If we have no file that means we are removing the avatar.
const optimisticData: OnyxUpdate[] = [
{
@@ -967,10 +977,67 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani
},
},
];
+
+ return {optimisticData, successData, failureData};
+}
+
+/**
+ * Updates the avatar for a group chat.
+ */
+function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageManipulatorResult) {
+ const {optimisticData, successData, failureData} = buildUpdateReportAvatarOnyxData(reportID, file);
const parameters: UpdateGroupChatAvatarParams = {file, reportID};
API.write(WRITE_COMMANDS.UPDATE_GROUP_CHAT_AVATAR, parameters, {optimisticData, failureData, successData});
}
+/**
+ * Updates the avatar for a policy room.
+ */
+function updatePolicyRoomAvatar(reportID: string, file?: File | CustomRNImageManipulatorResult) {
+ const avatarURL = file?.uri ?? '';
+ const {optimisticData, successData, failureData} = buildUpdateReportAvatarOnyxData(reportID, file);
+
+ const optimisticAction = buildOptimisticRoomAvatarUpdatedReportAction(avatarURL);
+ optimisticData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
+ value: {[optimisticAction.reportActionID]: optimisticAction},
+ });
+
+ // Update the report with last action details
+ optimisticData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+ value: {
+ lastActorAccountID: currentUserAccountID,
+ lastVisibleActionCreated: optimisticAction.created,
+ lastMessageText: (optimisticAction.message as Message[]).at(0)?.text,
+ },
+ });
+
+ // Add success data to clear pending action
+ successData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
+ value: {
+ [optimisticAction.reportActionID]: {pendingAction: null},
+ },
+ });
+
+ failureData.push({
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
+ value: {
+ [optimisticAction.reportActionID]: {
+ pendingAction: null,
+ },
+ },
+ });
+
+ const parameters: UpdateRoomAvatarParams = {reportID, file, reportActionID: optimisticAction.reportActionID};
+ API.write(WRITE_COMMANDS.UPDATE_ROOM_AVATAR, parameters, {optimisticData, failureData, successData});
+}
+
/**
* Clear error and pending fields for the report avatar
*/
@@ -6222,6 +6289,7 @@ export {
unsubscribeFromReportChannel,
updateDescription,
updateGroupChatAvatar,
+ updatePolicyRoomAvatar,
updateGroupChatMemberRoles,
updateChatName,
updateLastVisitTime,
diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx
index d84ff052ee21..f9e30c166e6d 100644
--- a/src/pages/ReportDetailsPage.tsx
+++ b/src/pages/ReportDetailsPage.tsx
@@ -19,6 +19,7 @@ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeed
import type {PromotedAction} from '@components/PromotedActionsBar';
import PromotedActionsBar, {PromotedActions} from '@components/PromotedActionsBar';
import ReportActionAvatars from '@components/ReportActionAvatars';
+import RoomHeaderAvatars from '@components/RoomHeaderAvatars';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import {useSearchContext} from '@components/Search/SearchContext';
@@ -591,6 +592,18 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail
) : null;
const renderedAvatar = useMemo(() => {
+ if (isChatRoom && !isThread) {
+ return (
+
+
+
+ );
+ }
if (!isGroupChat || isThread) {
return (
@@ -627,21 +640,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail
style={[styles.w100, styles.mb3]}
/>
);
- }, [
- isGroupChat,
- isThread,
- icons,
- report.avatarUrl,
- report.pendingFields?.avatar,
- report.errorFields?.avatar,
- report.reportID,
- styles.avatarXLarge,
- styles.smallEditIconAccount,
- styles.mt6,
- styles.w100,
- styles.mb3,
- moneyRequestReport,
- ]);
+ }, [isGroupChat, isThread, isChatRoom, icons, report, styles.avatarXLarge, styles.smallEditIconAccount, styles.mt6, styles.w100, styles.mb3, moneyRequestReport?.reportID]);
const canJoin = canJoinChat(report, parentReportAction, policy, !!reportNameValuePairs?.private_isArchived);
diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
index 9c82262e6aba..df4ee4f59f6c 100644
--- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
+++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx
@@ -50,6 +50,7 @@ import {
getRenamedAction,
getReopenedMessage,
getReportActionMessageText,
+ getRoomAvatarUpdatedMessage,
getTagListNameUpdatedMessage,
getTravelUpdateMessage,
getUpdatedApprovalRuleMessage,
@@ -683,6 +684,8 @@ const ContextMenuActions: ContextMenuAction[] = [
setClipboardMessage(getExportIntegrationMessageHTML(reportAction));
} else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_DESCRIPTION) {
setClipboardMessage(getUpdateRoomDescriptionMessage(reportAction));
+ } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.UPDATE_ROOM_AVATAR) {
+ setClipboardMessage(getRoomAvatarUpdatedMessage(reportAction));
} else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.ADD_EMPLOYEE) {
setClipboardMessage(getPolicyChangeLogAddEmployeeMessage(reportAction));
} else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.POLICY_CHANGE_LOG.UPDATE_EMPLOYEE) {
diff --git a/src/pages/media/AttachmentModalScreen/routes/report/ReportAvatarModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/report/ReportAvatarModalContent.tsx
index dd8e21db0aeb..ae5ed59d621c 100644
--- a/src/pages/media/AttachmentModalScreen/routes/report/ReportAvatarModalContent.tsx
+++ b/src/pages/media/AttachmentModalScreen/routes/report/ReportAvatarModalContent.tsx
@@ -1,6 +1,6 @@
import React, {useMemo} from 'react';
import useOnyx from '@hooks/useOnyx';
-import {getDefaultGroupAvatar, getPolicyName, getReportName, getWorkspaceIcon, isGroupChat, isThread} from '@libs/ReportUtils';
+import {getDefaultGroupAvatar, getPolicyName, getReportName, getWorkspaceIcon, isGroupChat, isThread, isUserCreatedPolicyRoom} from '@libs/ReportUtils';
import {getFullSizeAvatar} from '@libs/UserUtils';
import type {AttachmentModalBaseContentProps} from '@pages/media/AttachmentModalScreen/AttachmentModalBaseContent/types';
import AttachmentModalContainer from '@pages/media/AttachmentModalScreen/AttachmentModalContainer';
@@ -24,6 +24,13 @@ function ReportAvatarModalContent({navigation, route}: AttachmentModalScreenProp
isWorkspaceAvatar: false,
};
}
+ if (isUserCreatedPolicyRoom(report)) {
+ return {
+ source: report?.avatarUrl ? getFullSizeAvatar(report.avatarUrl, 0) : undefined,
+ headerTitle: getReportName(report),
+ isWorkspaceAvatar: false,
+ };
+ }
return {
source: getFullSizeAvatar(getWorkspaceIcon(report, policy).source, 0),
diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx
index 161b486a7179..3296438a3465 100644
--- a/src/pages/workspace/WorkspaceOverviewPage.tsx
+++ b/src/pages/workspace/WorkspaceOverviewPage.tsx
@@ -386,6 +386,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
source={policy?.avatarURL ?? ''}
avatarID={policy?.id}
size={CONST.AVATAR_SIZE.X_LARGE}
+ name={policyName}
avatarStyle={styles.avatarXLarge}
enablePreview
DefaultAvatar={DefaultAvatar}
diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts
index 8751b4c420d5..e86af9b86791 100644
--- a/src/types/onyx/OriginalMessage.ts
+++ b/src/types/onyx/OriginalMessage.ts
@@ -367,6 +367,9 @@ type OriginalMessageChangeLog = {
/** Name of the added category */
categoryName?: string;
+
+ /** Avatar URL of workspace room */
+ avatarURL?: string;
};
/** Model of change log */
diff --git a/tests/actions/EnforceActionExportRestrictions.ts b/tests/actions/EnforceActionExportRestrictions.ts
index be76cb9f5b02..5c467834715d 100644
--- a/tests/actions/EnforceActionExportRestrictions.ts
+++ b/tests/actions/EnforceActionExportRestrictions.ts
@@ -88,6 +88,11 @@ describe('ReportUtils', () => {
expect(ReportUtils.getIconsForGroupChat).toBeUndefined();
});
+ it('does not export getIconsForUserCreatedPolicyRoom', () => {
+ // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal
+ expect(ReportUtils.getIconsForUserCreatedPolicyRoom).toBeUndefined();
+ });
+
it('does not export getAllReportActions', () => {
// @ts-expect-error the test is asserting that it's undefined, so the TS error is normal
expect(ReportUtils.getAllReportActions).toBeUndefined();
diff --git a/tests/unit/ReportUtilsGetIconsTest.ts b/tests/unit/ReportUtilsGetIconsTest.ts
index 2b30796a0384..7441f8d04f80 100644
--- a/tests/unit/ReportUtilsGetIconsTest.ts
+++ b/tests/unit/ReportUtilsGetIconsTest.ts
@@ -21,6 +21,7 @@ import {
isSelfDM,
isTaskReport,
isThread,
+ isUserCreatedPolicyRoom,
isWorkspaceTaskReport,
isWorkspaceThread,
} from '@libs/ReportUtils';
@@ -215,6 +216,25 @@ describe('getIcons', () => {
expect(icons.at(0)?.name).toBe('Workspace-Test-001');
});
+ it('should return the correct icons for a user created policy room', () => {
+ const report: Report = {
+ ...LHNTestUtils.getFakeReport([], 0, true),
+ chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM,
+ policyID: '1',
+ avatarUrl: 'https://example.com/avatar.png',
+ };
+ const policy = LHNTestUtils.getFakePolicy('1');
+
+ // Verify report type conditions
+ expect(isUserCreatedPolicyRoom(report)).toBe(true);
+ expect(isChatReport(report)).toBe(true);
+
+ const icons = getIcons(report, FAKE_PERSONAL_DETAILS, null, '', -1, policy);
+ expect(icons).toHaveLength(1);
+ expect(icons.at(0)?.type).toBe(CONST.ICON_TYPE_WORKSPACE);
+ expect(icons.at(0)?.source).toBe('https://example.com/avatar.png');
+ });
+
it('should return the correct icons for a policy expense chat', () => {
const report: Report = {
...LHNTestUtils.getFakeReport([1], 0, true),