From 3242825452fd37c0ee2ad440553ccad0daa36527 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 2 Sep 2025 16:57:38 +0700 Subject: [PATCH 1/2] remove connect method --- package.json | 2 +- src/libs/actions/PersonalDetails.ts | 13 ++++--------- .../Profile/PersonalDetails/PersonalAddressPage.tsx | 6 ++++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 15ce4ae41b2d..10b7b5972a72 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand", "perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure", "typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc", - "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=216 --cache --cache-location=node_modules/.cache/eslint", + "lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=215 --cache --cache-location=node_modules/.cache/eslint", "lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh", "lint-watch": "npx eslint-watch --watch --changed", "shellcheck": "./scripts/shellCheck.sh", diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index b6cc91346a5c..fbd3c98709ab 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -29,8 +29,9 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {DateOfBirthForm} from '@src/types/form'; -import type {PersonalDetails, PrivatePersonalDetails} from '@src/types/onyx'; +import type {PersonalDetails} from '@src/types/onyx'; import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails'; +import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; let currentUserEmail = ''; let currentUserAccountID = -1; @@ -42,12 +43,6 @@ Onyx.connect({ }, }); -let privatePersonalDetails: OnyxEntry; -Onyx.connect({ - key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, - callback: (val) => (privatePersonalDetails = val), -}); - function updatePronouns(pronouns: string) { if (!currentUserAccountID) { return; @@ -222,7 +217,7 @@ function clearPhoneNumberError() { }); } -function updateAddress(street: string, street2: string, city: string, state: string, zip: string, country: Country | '') { +function updateAddress(addresses: Address[], street: string, street2: string, city: string, state: string, zip: string, country: Country | '') { const parameters: UpdateHomeAddressParams = { homeAddressStreet: street, addressStreet2: street2, @@ -245,7 +240,7 @@ function updateAddress(street: string, street2: string, city: string, state: str key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, value: { addresses: [ - ...(privatePersonalDetails?.addresses ?? []), + ...addresses, { street: PersonalDetailsUtils.getFormattedStreet(street, street2), city, diff --git a/src/pages/settings/Profile/PersonalDetails/PersonalAddressPage.tsx b/src/pages/settings/Profile/PersonalDetails/PersonalAddressPage.tsx index 4b6e89f065eb..f436add45d62 100644 --- a/src/pages/settings/Profile/PersonalDetails/PersonalAddressPage.tsx +++ b/src/pages/settings/Profile/PersonalDetails/PersonalAddressPage.tsx @@ -8,14 +8,16 @@ import type {FormOnyxValues} from '@src/components/Form/types'; import type {Country} from '@src/CONST'; import {updateAddress as updateAddressPersonalDetails} from '@src/libs/actions/PersonalDetails'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; /** * Submit form to update user's first and last legal name * @param values - form input values */ -function updateAddress(values: FormOnyxValues) { +function updateAddress(values: FormOnyxValues, addresses: Address[]) { updateAddressPersonalDetails( + addresses, values.addressLine1?.trim() ?? '', values.addressLine2?.trim() ?? '', values.city.trim(), @@ -40,7 +42,7 @@ function PersonalAddressPage() { defaultCountry={defaultCountry as Country} address={address} isLoadingApp={isLoadingApp} - updateAddress={updateAddress} + updateAddress={(values) => updateAddress(values, privatePersonalDetails?.addresses ?? [])} title={translate('privatePersonalDetails.address')} /> ); From 0eccf883632d51a89944c6de0e0e3e81e67b5173 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Tue, 2 Sep 2025 19:27:09 +0700 Subject: [PATCH 2/2] add UTs --- tests/actions/PersonalDetailsTest.ts | 105 +++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tests/actions/PersonalDetailsTest.ts b/tests/actions/PersonalDetailsTest.ts index 2216f1b32149..d039e6c93a7d 100644 --- a/tests/actions/PersonalDetailsTest.ts +++ b/tests/actions/PersonalDetailsTest.ts @@ -7,8 +7,10 @@ import Navigation from '@libs/Navigation/Navigation'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as UserUtils from '@libs/UserUtils'; import CONST from '@src/CONST'; +import type {Country} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalDetails} from '@src/types/onyx'; +import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; import * as PersonalDetailsActions from '../../src/libs/actions/PersonalDetails'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; @@ -41,6 +43,109 @@ describe('actions/PersonalDetails', () => { jest.restoreAllMocks(); }); + describe('updateAddress', () => { + it('should call API.write with correct parameters and optimistic data for US addresses and navigate back', async () => { + const addresses: Address[] = [ + { + street: 'Old Street', + city: 'Old City', + state: 'NY', + zip: '10001', + country: CONST.COUNTRY.US, + current: false, + }, + ]; + const street = '123 Main St'; + const street2 = 'Apt 4'; + const city = 'San Francisco'; + const state = 'CA'; + const zip = '94105'; + const country: Country | '' = CONST.COUNTRY.US; + + const formattedStreet = '123 Main St Apt 4'; + mockPersonalDetailsUtils.getFormattedStreet.mockReturnValue(formattedStreet); + + PersonalDetailsActions.updateAddress(addresses, street, street2, city, state, zip, country); + await waitForBatchedUpdates(); + + expect(mockAPI.write).toHaveBeenCalledWith( + WRITE_COMMANDS.UPDATE_HOME_ADDRESS, + { + homeAddressStreet: street, + addressStreet2: street2, + homeAddressCity: city, + addressState: state, + addressZipCode: zip, + addressCountry: country, + }, + { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, + value: { + addresses: [ + ...addresses, + { + street: formattedStreet, + city, + state, + zip, + country, + current: true, + }, + ], + }, + }, + ], + }, + ); + + expect(mockPersonalDetailsUtils.getFormattedStreet).toHaveBeenCalledWith(street, street2); + expect(mockNavigation.goBack).toHaveBeenCalledTimes(1); + }); + + it('should include addressStateLong for non-US addresses', async () => { + const addresses: Address[] = []; + const street = '10 Downing St'; + const street2 = ''; + const city = 'London'; + const state = 'Greater London'; + const zip = 'SW1A 2AA'; + const country: Country | '' = CONST.COUNTRY.GB; + + const formattedStreet = '10 Downing St'; + mockPersonalDetailsUtils.getFormattedStreet.mockReturnValue(formattedStreet); + + PersonalDetailsActions.updateAddress(addresses, street, street2, city, state, zip, country); + await waitForBatchedUpdates(); + + expect(mockAPI.write).toHaveBeenCalledWith( + WRITE_COMMANDS.UPDATE_HOME_ADDRESS, + { + homeAddressStreet: street, + addressStreet2: street2, + homeAddressCity: city, + addressState: state, + addressZipCode: zip, + addressCountry: country, + addressStateLong: state, + }, + expect.objectContaining({ + optimisticData: [ + expect.objectContaining({ + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, + }), + ], + }), + ); + + expect(mockPersonalDetailsUtils.getFormattedStreet).toHaveBeenCalledWith(street, street2); + expect(mockNavigation.goBack).toHaveBeenCalledTimes(1); + }); + }); + describe('updateLegalName', () => { const mockFormatPhoneNumber = jest.fn((phoneNumber: string) => phoneNumber);