Skip to content

Commit 56f5003

Browse files
committed
add submit manager tests
1 parent da4ae40 commit 56f5003

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

tests/actions/IOUTest/ReportWorkflowTest.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,142 @@ describe('actions/IOU/ReportWorkflow', () => {
11851185
expect(Navigation.navigate).not.toHaveBeenCalledWith(ROUTES.RESTRICTED_ACTION.getRoute(policyID));
11861186
}
11871187
});
1188+
1189+
it('preserves the existing report manager when cached policy data resolves to a different approver', async () => {
1190+
// eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting API.write calls to verify submit payload and optimistic data.
1191+
const apiWriteSpy = jest.spyOn(API, 'write').mockImplementation(() => Promise.resolve());
1192+
const policyID = '1';
1193+
const submitterAccountID = 100;
1194+
const correctManagerAccountID = 101;
1195+
const defaultApproverAccountID = 102;
1196+
const submitterEmail = 'submitter@example.com';
1197+
const correctManagerEmail = 'correct-manager@example.com';
1198+
const defaultApproverEmail = 'default-approver@example.com';
1199+
1200+
await Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, {
1201+
[submitterAccountID]: {accountID: submitterAccountID, login: submitterEmail},
1202+
[correctManagerAccountID]: {accountID: correctManagerAccountID, login: correctManagerEmail},
1203+
[defaultApproverAccountID]: {accountID: defaultApproverAccountID, login: defaultApproverEmail},
1204+
});
1205+
1206+
// Given cached policy data resolves to the default approver.
1207+
const policy: Policy = {
1208+
...createRandomPolicy(Number(policyID)),
1209+
id: policyID,
1210+
type: CONST.POLICY.TYPE.CORPORATE,
1211+
approvalMode: CONST.POLICY.APPROVAL_MODE.ADVANCED,
1212+
approver: defaultApproverEmail,
1213+
owner: defaultApproverEmail,
1214+
employeeList: {},
1215+
};
1216+
1217+
// And the report already has the correct manager.
1218+
const expenseReport: Report = {
1219+
...createRandomReport(Number(policyID), undefined),
1220+
reportID: '1',
1221+
policyID,
1222+
type: CONST.REPORT.TYPE.EXPENSE,
1223+
ownerAccountID: submitterAccountID,
1224+
managerID: correctManagerAccountID,
1225+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
1226+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
1227+
total: 1000,
1228+
currency: CONST.CURRENCY.USD,
1229+
};
1230+
1231+
// When submitting the report.
1232+
submitReport({
1233+
expenseReport,
1234+
policy,
1235+
currentUserAccountIDParam: submitterAccountID,
1236+
currentUserEmailParam: submitterEmail,
1237+
hasViolations: false,
1238+
isASAPSubmitBetaEnabled: false,
1239+
expenseReportCurrentNextStepDeprecated: undefined,
1240+
userBillingGracePeriodEnds: undefined,
1241+
amountOwed: 0,
1242+
ownerBillingGracePeriodEnd: undefined,
1243+
delegateEmail: undefined,
1244+
});
1245+
1246+
// Then the API payload and optimistic report update preserve the existing manager.
1247+
const [, parameters, onyxData] = apiWriteSpy.mock.calls.at(0) as [unknown, {managerAccountID?: number}, OnyxData<typeof ONYXKEYS.COLLECTION.REPORT>];
1248+
expect(parameters.managerAccountID).toBe(correctManagerAccountID);
1249+
1250+
const optimisticReportUpdate = onyxData.optimisticData?.find((update) => update.key === `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`);
1251+
expect((optimisticReportUpdate?.value as Report | undefined)?.managerID).toBe(correctManagerAccountID);
1252+
1253+
apiWriteSpy.mockRestore();
1254+
});
1255+
1256+
it('ignores the existing report manager when it points to the submitter', async () => {
1257+
// eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting API.write calls to verify submit payload and optimistic data.
1258+
const apiWriteSpy = jest.spyOn(API, 'write').mockImplementation(() => Promise.resolve());
1259+
const policyID = '1';
1260+
const submitterAccountID = 100;
1261+
const computedManagerAccountID = 101;
1262+
const submitterEmail = 'submitter@example.com';
1263+
const computedManagerEmail = 'computed-manager@example.com';
1264+
1265+
await Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, {
1266+
[submitterAccountID]: {accountID: submitterAccountID, login: submitterEmail},
1267+
[computedManagerAccountID]: {accountID: computedManagerAccountID, login: computedManagerEmail},
1268+
});
1269+
1270+
// Given cached policy data resolves to the configured approver.
1271+
const policy: Policy = {
1272+
...createRandomPolicy(Number(policyID)),
1273+
id: policyID,
1274+
type: CONST.POLICY.TYPE.CORPORATE,
1275+
approvalMode: CONST.POLICY.APPROVAL_MODE.ADVANCED,
1276+
approver: computedManagerEmail,
1277+
owner: computedManagerEmail,
1278+
employeeList: {
1279+
[submitterEmail]: {
1280+
email: submitterEmail,
1281+
submitsTo: computedManagerEmail,
1282+
},
1283+
},
1284+
};
1285+
1286+
// And the draft report manager is still the submitter.
1287+
const expenseReport: Report = {
1288+
...createRandomReport(Number(policyID), undefined),
1289+
reportID: '1',
1290+
policyID,
1291+
type: CONST.REPORT.TYPE.EXPENSE,
1292+
ownerAccountID: submitterAccountID,
1293+
managerID: submitterAccountID,
1294+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
1295+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
1296+
total: 1000,
1297+
currency: CONST.CURRENCY.USD,
1298+
};
1299+
1300+
// When submitting the report.
1301+
submitReport({
1302+
expenseReport,
1303+
policy,
1304+
currentUserAccountIDParam: submitterAccountID,
1305+
currentUserEmailParam: submitterEmail,
1306+
hasViolations: false,
1307+
isASAPSubmitBetaEnabled: false,
1308+
expenseReportCurrentNextStepDeprecated: undefined,
1309+
userBillingGracePeriodEnds: undefined,
1310+
amountOwed: 0,
1311+
ownerBillingGracePeriodEnd: undefined,
1312+
delegateEmail: undefined,
1313+
});
1314+
1315+
// Then the API payload and optimistic report update use the configured approver instead of routing to the submitter.
1316+
const [, parameters, onyxData] = apiWriteSpy.mock.calls.at(0) as [unknown, {managerAccountID?: number}, OnyxData<typeof ONYXKEYS.COLLECTION.REPORT>];
1317+
expect(parameters.managerAccountID).toBe(computedManagerAccountID);
1318+
1319+
const optimisticReportUpdate = onyxData.optimisticData?.find((update) => update.key === `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`);
1320+
expect((optimisticReportUpdate?.value as Report | undefined)?.managerID).toBe(computedManagerAccountID);
1321+
1322+
apiWriteSpy.mockRestore();
1323+
});
11881324
});
11891325

11901326
describe('delegateAccountID forwarding', () => {
@@ -1193,6 +1329,7 @@ describe('actions/IOU/ReportWorkflow', () => {
11931329

11941330
beforeEach(async () => {
11951331
jest.clearAllMocks();
1332+
// eslint-disable-next-line rulesdir/no-multiple-api-calls -- Inspecting API.write calls to verify optimistic data.
11961333
jest.spyOn(API, 'write');
11971334
await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {
11981335
[DELEGATE_ACCOUNT_ID]: {

0 commit comments

Comments
 (0)