Skip to content

Commit 5ac004d

Browse files
authored
Merge pull request Expensify#93056 from Expensify/fix/main-ts-policy-member-args
[No QA] Fix TypeScript and ESLint failures on main (PolicyMemberTest + ReportLayout/useHoldRejectActions)
2 parents 3a3b804 + e4ed4ef commit 5ac004d

4 files changed

Lines changed: 59 additions & 25 deletions

File tree

config/eslint/eslint.seatbelt.tsv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@
273273
"../../src/components/MoneyRequestConfirmationList/sections/AmountField.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
274274
"../../src/components/MoneyRequestConfirmationList/sections/AttendeeField.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
275275
"../../src/components/MoneyRequestConfirmationList/sections/TaxFields.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
276-
"../../src/components/MoneyRequestConfirmationList/sections/selectors.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
276+
"../../src/components/MoneyRequestConfirmationList/sections/selectors.ts" "@typescript-eslint/no-unsafe-type-assertion" 7
277277
"../../src/components/MoneyRequestConfirmationListFooter/ConfirmationReceiptThumbnail.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
278278
"../../src/components/MoneyRequestConfirmationListFooter/hooks/useReceiptThumbnailSource.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
279279
"../../src/components/MoneyRequestConfirmationListFooter/sections/DistanceMapSection.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
@@ -682,7 +682,7 @@
682682
"../../src/libs/Navigation/AppNavigator/routerExtensions/addRootHistoryRouterExtension.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
683683
"../../src/libs/Navigation/AppNavigator/routerExtensions/addRootHistoryRouterExtensionUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
684684
"../../src/libs/Navigation/DebugTabNavigator.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
685-
"../../src/libs/Navigation/Navigation.ts" "@typescript-eslint/no-unsafe-type-assertion" 10
685+
"../../src/libs/Navigation/Navigation.ts" "@typescript-eslint/no-unsafe-type-assertion" 11
686686
"../../src/libs/Navigation/Navigation.ts" "no-restricted-imports" 1
687687
"../../src/libs/Navigation/OnyxTabNavigator.tsx" "@typescript-eslint/no-unsafe-type-assertion" 4
688688
"../../src/libs/Navigation/PlatformStackNavigation/ScreenLayout.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
@@ -777,7 +777,7 @@
777777
"../../src/libs/SearchAutocompleteUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 4
778778
"../../src/libs/SearchQueryUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 73
779779
"../../src/libs/SearchUIUtils.ts" "@typescript-eslint/no-deprecated/getSearchReportName" 1
780-
"../../src/libs/SearchUIUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 69
780+
"../../src/libs/SearchUIUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 71
781781
"../../src/libs/SelectionScraper/index.ts" "@typescript-eslint/no-unsafe-type-assertion" 4
782782
"../../src/libs/SidebarUtils.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
783783
"../../src/libs/Sound/index.native.ts" "@typescript-eslint/no-unsafe-type-assertion" 4
@@ -1569,7 +1569,7 @@
15691569
"../../src/utils/times.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
15701570
"../../tests/actions/AppTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 4
15711571
"../../tests/actions/BankAccountsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 2
1572-
"../../tests/actions/CopyPolicySettingsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 16
1572+
"../../tests/actions/CopyPolicySettingsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 18
15731573
"../../tests/actions/DomainTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 20
15741574
"../../tests/actions/IOU/BuildOnyxDataForMoneyRequestTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 17
15751575
"../../tests/actions/IOU/GetMoneyRequestInformationTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
@@ -1759,7 +1759,7 @@
17591759
"../../tests/unit/ContactMethodDetailsPageTest.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
17601760
"../../tests/unit/ContextMenuActionsCopyMessageTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 3
17611761
"../../tests/unit/CopyPolicySettingsProgressModalTest.tsx" "@typescript-eslint/no-unsafe-type-assertion" 4
1762-
"../../tests/unit/CopyPolicySettingsUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 1
1762+
"../../tests/unit/CopyPolicySettingsUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 3
17631763
"../../tests/unit/CountryUtils.test.ts" "@typescript-eslint/no-unsafe-type-assertion" 9
17641764
"../../tests/unit/DateUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 22
17651765
"../../tests/unit/DebugUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 24
@@ -1852,7 +1852,7 @@
18521852
"../../tests/unit/Search/SearchListRenderCountTest.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2
18531853
"../../tests/unit/Search/SearchQueryUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 9
18541854
"../../tests/unit/Search/SearchSingleSelectionPickerTest.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
1855-
"../../tests/unit/Search/SearchUIUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 133
1855+
"../../tests/unit/Search/SearchUIUtilsTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 135
18561856
"../../tests/unit/Search/buildCardFilterDataTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 22
18571857
"../../tests/unit/Search/buildSubstitutionsMapTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 3
18581858
"../../tests/unit/Search/getSpendOverTimeStateTest.ts" "@typescript-eslint/no-unsafe-type-assertion" 2

tests/actions/PolicyMemberTest.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ describe('actions/PolicyMember', () => {
478478

479479
mockFetch?.pause?.();
480480
// When the caller passes ROLE.USER for a Submit workspace
481-
Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser);
481+
Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser, {});
482482

483483
await waitForBatchedUpdates();
484484

@@ -511,7 +511,7 @@ describe('actions/PolicyMember', () => {
511511

512512
mockFetch?.pause?.();
513513
// When the caller passes ROLE.USER on a non-Submit workspace
514-
Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser);
514+
Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser, {});
515515

516516
await waitForBatchedUpdates();
517517

@@ -554,7 +554,7 @@ describe('actions/PolicyMember', () => {
554554

555555
// When inviting a new member on a Submit workspace (role is forced to Editor)
556556
mockFetch?.pause?.();
557-
Member.addMembersToWorkspace({[editorEmail]: editorAccountID}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser);
557+
Member.addMembersToWorkspace({[editorEmail]: editorAccountID}, 'Welcome', policy, [], CONST.POLICY.ROLE.USER, TestHelper.formatPhoneNumber, currentUser, {});
558558

559559
await waitForBatchedUpdates();
560560

tests/actions/ReportLayoutTest.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,36 @@ import CONST from '@src/CONST';
66

77
jest.mock('@libs/API');
88

9-
const mockAPI = API as jest.Mocked<typeof API>;
9+
const mockWrite = jest.mocked(API.write);
1010

1111
const LAYOUT_OPTION_NVP_NAME = 'expensify_layoutOption';
1212
const GROUP_BY_OPTION_NVP_NAME = 'expensify_groupByOption';
1313

14+
function isRecord(value: unknown): value is Record<PropertyKey, unknown> {
15+
return typeof value === 'object' && value !== null;
16+
}
17+
18+
function isSetNameValuePairsParams(value: unknown): value is SetNameValuePairsParams {
19+
return isRecord(value) && 'nameValuePairs' in value && typeof value.nameValuePairs === 'string';
20+
}
21+
22+
function isStringRecord(value: unknown): value is Record<string, string> {
23+
return isRecord(value) && Object.values(value).every((entry) => typeof entry === 'string');
24+
}
25+
1426
const getWrittenNameValuePairs = (callIndex = 0) => {
15-
const call = mockAPI.write.mock.calls.at(callIndex);
16-
const params = call?.[1] as SetNameValuePairsParams | undefined;
17-
return params ? (JSON.parse(params.nameValuePairs) as Record<string, string>) : {};
27+
const call = mockWrite.mock.calls.at(callIndex);
28+
const params = call?.[1];
29+
if (!isSetNameValuePairsParams(params)) {
30+
return {};
31+
}
32+
33+
const parsed: unknown = JSON.parse(params.nameValuePairs);
34+
if (!isStringRecord(parsed)) {
35+
return {};
36+
}
37+
38+
return parsed;
1839
};
1940

2041
describe('getReportLayoutGroupBy', () => {
@@ -45,14 +66,14 @@ describe('getReportLayoutGroupBy', () => {
4566

4667
describe('setReportLayout', () => {
4768
beforeEach(() => {
48-
mockAPI.write.mockClear();
69+
mockWrite.mockClear();
4970
});
5071

5172
it('writes layoutOption=matrix and clears groupByOption atomically when None is selected', () => {
5273
setReportLayout(CONST.REPORT_LAYOUT.LAYOUT_OPTION.MATRIX, null, CONST.REPORT_LAYOUT.GROUP_BY.TAG);
5374

54-
expect(mockAPI.write).toHaveBeenCalledTimes(1);
55-
expect(mockAPI.write.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
75+
expect(mockWrite).toHaveBeenCalledTimes(1);
76+
expect(mockWrite.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
5677
expect(getWrittenNameValuePairs()).toEqual({
5778
[LAYOUT_OPTION_NVP_NAME]: CONST.REPORT_LAYOUT.LAYOUT_OPTION.MATRIX,
5879
[GROUP_BY_OPTION_NVP_NAME]: '',
@@ -62,16 +83,16 @@ describe('setReportLayout', () => {
6283
it('writes only groupByOption when Category or Tag is selected without a prior matrix layout', () => {
6384
setReportLayout(CONST.REPORT_LAYOUT.GROUP_BY.TAG, null, null);
6485

65-
expect(mockAPI.write).toHaveBeenCalledTimes(1);
66-
expect(mockAPI.write.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
86+
expect(mockWrite).toHaveBeenCalledTimes(1);
87+
expect(mockWrite.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
6788
expect(getWrittenNameValuePairs()).toEqual({[GROUP_BY_OPTION_NVP_NAME]: CONST.REPORT_LAYOUT.GROUP_BY.TAG});
6889
});
6990

7091
it('clears the matrix layout atomically when switching from None back to Category or Tag', () => {
7192
setReportLayout(CONST.REPORT_LAYOUT.GROUP_BY.CATEGORY, CONST.REPORT_LAYOUT.LAYOUT_OPTION.MATRIX, null);
7293

73-
expect(mockAPI.write).toHaveBeenCalledTimes(1);
74-
expect(mockAPI.write.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
94+
expect(mockWrite).toHaveBeenCalledTimes(1);
95+
expect(mockWrite.mock.calls.at(0)?.[0]).toBe(WRITE_COMMANDS.SET_NAME_VALUE_PAIRS);
7596
expect(getWrittenNameValuePairs()).toEqual({
7697
[GROUP_BY_OPTION_NVP_NAME]: CONST.REPORT_LAYOUT.GROUP_BY.CATEGORY,
7798
[LAYOUT_OPTION_NVP_NAME]: '',
@@ -81,7 +102,7 @@ describe('setReportLayout', () => {
81102
it('never falls back to the singular SetNameValuePair command', () => {
82103
setReportLayout(CONST.REPORT_LAYOUT.GROUP_BY.TAG, null, null);
83104

84-
expect(mockAPI.write).not.toHaveBeenCalledWith(WRITE_COMMANDS.SET_NAME_VALUE_PAIR, expect.any(Object), expect.any(Object));
105+
expect(mockWrite).not.toHaveBeenCalledWith(WRITE_COMMANDS.SET_NAME_VALUE_PAIR, expect.any(Object), expect.any(Object));
85106
});
86107
});
87108

tests/unit/hooks/useHoldRejectActionsTest.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {renderHook} from '@testing-library/react-native';
22
import Onyx from 'react-native-onyx';
3+
import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider';
34
import useHoldRejectActions from '@hooks/useHoldRejectActions';
45
import CONST from '@src/CONST';
56
import ONYXKEYS from '@src/ONYXKEYS';
@@ -65,7 +66,19 @@ jest.mock('@libs/ReportUtils', () => ({
6566
changeMoneyRequestHoldStatus: jest.fn(),
6667
}));
6768

68-
const DelegateProvider = require('@components/DelegateNoAccessModalProvider') as Record<string, jest.Mock>;
69+
function getMockUseDelegateNoAccessState() {
70+
if (!jest.isMockFunction(useDelegateNoAccessState)) {
71+
throw new Error('useDelegateNoAccessState must be mocked');
72+
}
73+
return useDelegateNoAccessState;
74+
}
75+
76+
function getMockUseDelegateNoAccessActions() {
77+
if (!jest.isMockFunction(useDelegateNoAccessActions)) {
78+
throw new Error('useDelegateNoAccessActions must be mocked');
79+
}
80+
return useDelegateNoAccessActions;
81+
}
6982

7083
const mockReport: Report = {
7184
reportID: TEST_REPORT_ID,
@@ -96,8 +109,8 @@ describe('useHoldRejectActions - report-level reject', () => {
96109
await Onyx.clear();
97110
await waitForBatchedUpdates();
98111
jest.clearAllMocks();
99-
DelegateProvider.useDelegateNoAccessState.mockReturnValue({isDelegateAccessRestricted: false});
100-
DelegateProvider.useDelegateNoAccessActions.mockReturnValue({showDelegateNoAccessModal: mockShowDelegateNoAccessModal});
112+
getMockUseDelegateNoAccessState().mockReturnValue({isDelegateAccessRestricted: false});
113+
getMockUseDelegateNoAccessActions().mockReturnValue({showDelegateNoAccessModal: mockShowDelegateNoAccessModal});
101114
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${TEST_REPORT_ID}`, mockReport);
102115
});
103116

@@ -124,7 +137,7 @@ describe('useHoldRejectActions - report-level reject', () => {
124137
});
125138

126139
it('shows the delegate no-access modal and does nothing else when delegate access is restricted', async () => {
127-
DelegateProvider.useDelegateNoAccessState.mockReturnValue({isDelegateAccessRestricted: true});
140+
getMockUseDelegateNoAccessState().mockReturnValue({isDelegateAccessRestricted: true});
128141
await Onyx.merge(ONYXKEYS.NVP_DISMISSED_REJECT_USE_EXPLANATION, false);
129142
await waitForBatchedUpdates();
130143

0 commit comments

Comments
 (0)