Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: moving expense to selfDM message not correct #56202

17 changes: 13 additions & 4 deletions src/libs/ModifiedExpenseMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Log from './Log';
import {getCleanedTagName, getSortedTagKeys} from './PolicyUtils';
import {getOriginalMessage, isModifiedExpenseAction} from './ReportActionsUtils';
// eslint-disable-next-line import/no-cycle
import {buildReportNameFromParticipantNames, getPolicyExpenseChatName, getPolicyName, getRootParentReport, isPolicyExpenseChat} from './ReportUtils';
import {buildReportNameFromParticipantNames, getPolicyExpenseChatName, getPolicyName, getRootParentReport, isPolicyExpenseChat, isSelfDM} from './ReportUtils';
import {getTagArrayFromName} from './TransactionUtils';

let allPolicyTags: OnyxCollection<PolicyTagLists> = {};
Expand Down Expand Up @@ -139,11 +139,20 @@ function getForDistanceRequest(newMerchant: string, oldMerchant: string, newAmou
function getForExpenseMovedFromSelfDM(destinationReportID: string) {
const destinationReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${destinationReportID}`];
const rootParentReport = getRootParentReport(destinationReport);

// The "Move report" flow only supports moving expenses to a policy expense chat or a 1:1 DM.
// The "Move report" flow only supports moving expenses from selfDM to:
// 1. A policy expense chat
// 2. A 1:1 DM
// However, in the olddot, expenses could be moved back to a self-DM.
// To maintain consistency and handle this case, we provide a fallback message.
if (isSelfDM(rootParentReport)) {
return translateLocal('iou.changedTheExpense');
}
const reportName = isPolicyExpenseChat(rootParentReport) ? getPolicyExpenseChatName(rootParentReport) : buildReportNameFromParticipantNames({report: rootParentReport});
const policyName = getPolicyName(rootParentReport, true);

// If we can't determine either the report name or policy name, return the default message
if (isEmpty(policyName) && !reportName) {
return translateLocal('iou.changedTheExpense');
}
return translateLocal('iou.movedFromSelfDM', {
reportName,
workspaceName: !isEmpty(policyName) ? policyName : undefined,
Expand Down
112 changes: 112 additions & 0 deletions tests/unit/ModifiedExpenseMessageTest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import Onyx from 'react-native-onyx';
import ModifiedExpenseMessage from '@libs/ModifiedExpenseMessage';
import CONST from '@src/CONST';
import {translate} from '@src/libs/Localize';
import ONYXKEYS from '@src/ONYXKEYS';
import createRandomReportAction from '../utils/collections/reportActions';
import createRandomReport from '../utils/collections/reports';
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';

describe('ModifiedExpenseMessage', () => {
describe('getForAction', () => {
Expand Down Expand Up @@ -396,5 +400,113 @@ describe('ModifiedExpenseMessage', () => {
expect(result).toEqual(expectedResult);
});
});

describe('when moving an expense', () => {
beforeEach(() => Onyx.clear());
it('return the message "changed the expense" when moving an expense from an expense chat or 1:1 DM to selfDM', async () => {
// Given the selfDM report and report action
const selfDMReport = {
...report,
chatType: CONST.REPORT.CHAT_TYPE.SELF_DM,
};
const reportAction = {
...createRandomReportAction(1),
actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE,
originalMessage: {
movedToReportID: selfDMReport.reportID,
},
};
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}`, {[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReport.reportID}`]: selfDMReport});
await waitForBatchedUpdates();

// Given the correct text message
const expectedResult = translate(CONST.LOCALES.EN as 'en', 'iou.changedTheExpense');

// When the expense is moved from an expense chat or 1:1 DM to selfDM
const result = ModifiedExpenseMessage.getForReportAction(selfDMReport.reportID, reportAction);
// Then it should return the 'changed the expense' message
expect(result).toEqual(expectedResult);
});

it('return the message "changed the expense" when reportName and workspace name are empty', async () => {
// Given the policyExpenseChat with reportName is empty and report action
const policyExpenseChat = {
...report,
chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT,
reportName: '',
isOwnPolicyExpenseChat: false,
};
const reportAction = {
...createRandomReportAction(1),
actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE,
originalMessage: {
movedToReportID: policyExpenseChat.reportID,
},
};
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}`, {[`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseChat.reportID}`]: policyExpenseChat});
await waitForBatchedUpdates();

// Given the correct text message
const expectedResult = translate(CONST.LOCALES.EN as 'en', 'iou.changedTheExpense');

// When the expense is moved to an expense chat with reportName empty
const result = ModifiedExpenseMessage.getForReportAction(policyExpenseChat.reportID, reportAction);
// Then it should return the 'changed the expense' message
expect(result).toEqual(expectedResult);
});

it('return the message "moved expense from self DM to policyName" when both reportName and policyName are present', async () => {
// Given the policyExpenseChat with both reportName and policyName are present and report action
const policyExpenseChat = {
...report,
chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT,
isOwnPolicyExpenseChat: false,
policyName: 'fake policyName',
};
const reportAction = {
...createRandomReportAction(1),
actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE,
originalMessage: {
movedToReportID: policyExpenseChat.reportID,
},
};
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}`, {[`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseChat.reportID}`]: policyExpenseChat});
await waitForBatchedUpdates();

// Given the correct text message
const expectedResult = translate(CONST.LOCALES.EN as 'en', 'iou.movedFromSelfDM', {reportName: policyExpenseChat.reportName, workspaceName: policyExpenseChat.policyName});

// When the expense is moved to an expense chat with both reportName and policyName are present
const result = ModifiedExpenseMessage.getForReportAction(policyExpenseChat.reportID, reportAction);
// Then it should return the correct text message
expect(result).toEqual(expectedResult);
});

it('return the message "moved expense from self DM to chat with reportName" when only reportName is present', async () => {
// Given the policyExpenseChat with only reportName is present and report action
const policyExpenseChat = {
...report,
chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT,
isOwnPolicyExpenseChat: false,
};
const reportAction = {
...createRandomReportAction(1),
actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE,
originalMessage: {
movedToReportID: policyExpenseChat.reportID,
},
};
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}`, {[`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseChat.reportID}`]: policyExpenseChat});
await waitForBatchedUpdates();

// Given the correct text message
const expectedResult = translate(CONST.LOCALES.EN as 'en', 'iou.movedFromSelfDM', {reportName: policyExpenseChat.reportName});

// When the expense is moved to an expense chat with only reportName is present
const result = ModifiedExpenseMessage.getForReportAction(policyExpenseChat.reportID, reportAction);
// Then it should return the correct text message
expect(result).toEqual(expectedResult);
});
});
});
});
Loading