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: Not here page when create new request #50847

Merged
merged 31 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
63ee178
fix: Not here page when create new request
nkdengineer Oct 16, 2024
af0736f
Merge branch 'main' into fix/49801
nkdengineer Oct 18, 2024
3036aa5
Merge branch 'main' into fix/49801
nkdengineer Oct 20, 2024
a3ee088
fix: logic merge chat report
nkdengineer Oct 21, 2024
0968f36
Merge branch 'main' into fix/49801
nkdengineer Oct 29, 2024
366f55c
Merge branch 'main' into fix/49801
nkdengineer Oct 29, 2024
2bcbb1d
Merge branch 'main' into fix/49801
nkdengineer Oct 29, 2024
9bcc69a
Merge branch 'main' into fix/49801
nkdengineer Nov 12, 2024
21c48aa
Merge branch 'main' into fix/49801
nkdengineer Nov 21, 2024
3c26e0a
Merge branch 'main' into fix/49801
nkdengineer Nov 21, 2024
9958e46
Merge branch 'main' into fix/49801
nkdengineer Nov 22, 2024
ad40868
Merge branch 'main' into fix/49801
nkdengineer Nov 25, 2024
6194ced
fix: not show create expense button when it closed
nkdengineer Nov 25, 2024
1680b85
add comment
nkdengineer Nov 27, 2024
b3d6e40
Merge branch 'main' into fix/49801
nkdengineer Nov 28, 2024
36bb786
fix: add test for cancel payment
nkdengineer Nov 28, 2024
b87a545
Merge branch 'main' into fix/49801
nkdengineer Dec 3, 2024
54bc206
Merge branch 'main' into fix/49801
nkdengineer Dec 3, 2024
ff6c9e8
Add test for cancel payment
nkdengineer Dec 3, 2024
c7baeff
Merge branch 'main' into fix/49801
nkdengineer Dec 5, 2024
09f9232
fix: add comment for cancel payment test
nkdengineer Dec 5, 2024
6f32587
Merge branch 'main' into fix/49801
nkdengineer Dec 5, 2024
0a6267d
implement getOnyxData function
nkdengineer Dec 5, 2024
852b2c7
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
9cd80de
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
2e58d79
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
5345480
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
8591f66
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
3c846b6
Update tests/actions/IOUTest.ts
nkdengineer Dec 5, 2024
6a86cdc
Merge branch 'main' into fix/49801
nkdengineer Dec 9, 2024
730f3ff
use getOnyxData
nkdengineer Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1807,7 +1807,7 @@ function canAddOrDeleteTransactions(moneyRequestReport: OnyxEntry<Report>): bool
return isAwaitingFirstLevelApproval(moneyRequestReport);
}

if (isReportApproved(moneyRequestReport) || isSettled(moneyRequestReport?.reportID)) {
if (isReportApproved(moneyRequestReport) || isClosedReport(moneyRequestReport) || isSettled(moneyRequestReport?.reportID)) {
return false;
}

Expand Down
12 changes: 12 additions & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7522,6 +7522,10 @@ function cancelPayment(expenseReport: OnyxEntry<OnyxTypes.Report>, chatReport: O
const stateNum: ValueOf<typeof CONST.REPORT.STATE_NUM> = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.APPROVED;
const statusNum: ValueOf<typeof CONST.REPORT.STATUS_NUM> = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATUS_NUM.CLOSED : CONST.REPORT.STATUS_NUM.APPROVED;
const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, statusNum);
const iouReportActions = ReportActionsUtils.getAllReportActions(chatReport.iouReportID ?? '-1');
const expenseReportActions = ReportActionsUtils.getAllReportActions(expenseReport.reportID ?? '-1');
const iouCreatedAction = Object.values(iouReportActions).find((action) => ReportActionsUtils.isCreatedAction(action));
const expenseCreatedAction = Object.values(expenseReportActions).find((action) => ReportActionsUtils.isCreatedAction(action));
const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand All @@ -7533,6 +7537,14 @@ function cancelPayment(expenseReport: OnyxEntry<OnyxTypes.Report>, chatReport: O
},
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`,
value: {
// The report created later will become the iouReportID of the chat report
iouReportID: (iouCreatedAction?.created ?? '') > (expenseCreatedAction?.created ?? '') ? chatReport?.iouReportID : expenseReport.reportID,
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`,
Expand Down
98 changes: 98 additions & 0 deletions tests/actions/IOUTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,104 @@ describe('actions/IOU', () => {
});
});

describe('a workspace chat with a cancelled payment', () => {
const amount = 10000;
const comment = '💸💸💸💸';
const merchant = 'NASDAQ';

afterEach(() => {
mockFetch?.resume?.();
});

it("has an iouReportID of the cancelled payment's expense report", () => {
let expenseReport: OnyxEntry<OnyxTypes.Report>;
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
let chatReport: OnyxEntry<OnyxTypes.Report>;

Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
return waitForBatchedUpdates()
.then(() => {
PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
return waitForBatchedUpdates();
})
.then(
() =>
new Promise<void>((resolve) => {
const connection = Onyx.connect({
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (allReports) => {
Onyx.disconnect(connection);
chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);

resolve();
},
});
}),
)
.then(() => {
if (chatReport) {
// When a submit IOU expense is made
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
IOU.requestMoney({
report: chatReport,
participantParams: {
payeeEmail: RORY_EMAIL,
payeeAccountID: RORY_ACCOUNT_ID,
participant: {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID},
},
transactionParams: {
amount,
attendees: [],
currency: CONST.CURRENCY.USD,
created: '',
merchant,
comment,
},
});
}
return waitForBatchedUpdates();
})
.then(() =>
TestHelper.getOnyxData({
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (allReports) => {
expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
},
}),
)
.then(() => {
if (chatReport && expenseReport) {
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, chatReport, expenseReport);
}
return waitForBatchedUpdates();
})
.then(() => {
if (chatReport && expenseReport) {
// When we attempt to cancle payment an expense from the expense report
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
IOU.cancelPayment(expenseReport, chatReport);
}
return waitForBatchedUpdates();
})
.then(
() =>
new Promise<void>((resolve) => {
const connection = Onyx.connect({
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
// When fetching all reports from Onyx
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
callback: (allReports) => {
Onyx.disconnect(connection);
const chatReportData = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`];
// Then we should find an IOU action with specific properties
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
expect(chatReportData?.iouReportID).toBe(expenseReport?.reportID);
resolve();
},
});
}),
);
});
});

describe('deleteMoneyRequest', () => {
const amount = 10000;
const comment = 'Send me money please';
Expand Down
19 changes: 19 additions & 0 deletions tests/utils/TestHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {fireEvent, screen} from '@testing-library/react-native';
import {Str} from 'expensify-common';
import {Linking} from 'react-native';
import Onyx from 'react-native-onyx';
import type {ConnectOptions} from 'react-native-onyx/dist/types';
import type {ApiCommand, ApiRequestCommandParameters} from '@libs/API/types';
import * as Localize from '@libs/Localize';
import * as Pusher from '@libs/Pusher/pusher';
Expand All @@ -12,6 +13,7 @@ import * as Session from '@src/libs/actions/Session';
import HttpUtils from '@src/libs/HttpUtils';
import * as NumberUtils from '@src/libs/NumberUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import type {OnyxKey} from '@src/ONYXKEYS';
import appSetup from '@src/setup';
import type {Response as OnyxResponse, PersonalDetails, Report} from '@src/types/onyx';
import waitForBatchedUpdates from './waitForBatchedUpdates';
Expand All @@ -25,6 +27,9 @@ type MockFetch = jest.MockedFn<typeof fetch> & {
mockAPICommand: <TCommand extends ApiCommand>(command: TCommand, responseHandler: (params: ApiRequestCommandParameters[TCommand]) => OnyxResponse) => void;
};

type ConnectionCallback<TKey extends OnyxKey> = NonNullable<ConnectOptions<TKey>['callback']>;
type ConnectionCallbackParams<TKey extends OnyxKey> = Parameters<ConnectionCallback<TKey>>;

type QueueItem = {
resolve: (value: Partial<Response> | PromiseLike<Partial<Response>>) => void;
input: RequestInfo;
Expand Down Expand Up @@ -65,6 +70,19 @@ function buildPersonalDetails(login: string, accountID: number, firstName = 'Tes
};
}

function getOnyxData<TKey extends OnyxKey>(options: ConnectOptions<TKey>) {
return new Promise<void>((resolve) => {
const connectionID = Onyx.connect({
...options,
callback: (...params: ConnectionCallbackParams<TKey>) => {
Onyx.disconnect(connectionID);
(options.callback as (...args: ConnectionCallbackParams<TKey>) => void)?.(...params);
resolve();
},
});
});
}

/**
* Simulate signing in and make sure all API calls in this flow succeed. Every time we add
* a mockImplementationOnce() we are altering what Network.post() will return.
Expand Down Expand Up @@ -335,4 +353,5 @@ export {
expectAPICommandToHaveBeenCalledWith,
setupGlobalFetchMock,
navigateToSidebarOption,
getOnyxData,
};
Loading