-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Fix: Resolve MISSING TRANSLATION error in country picker for legacy data #70844
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
Merged
dangrous
merged 28 commits into
Expensify:main
from
abzokhattab:fix/country-picker-missing-translation
Oct 6, 2025
+196
−2
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
16eabf7
Fix: Resolve MISSING TRANSLATION error in country picker for legacy data
abzokhattab d67d2f3
refactoring the getCountryCode function
abzokhattab 3d40b2d
fixing eslint
abzokhattab 7e0d4a6
fixing spellcheck
abzokhattab 5166a66
fixing eslint
abzokhattab 0d4c5f6
Merge remote-tracking branch 'origin/main' into fix/country-picker-mi…
abzokhattab 83e5de7
Merge remote-tracking branch 'origin/main' into fix/country-picker-mi…
abzokhattab 352e473
fix tranlsation errs of private_personalDetails.addresses
abzokhattab 3654b18
fix eslint
abzokhattab 6103255
fixing eslint
abzokhattab 298d8c5
fixing eslint
abzokhattab fddd420
eslint fix
abzokhattab 1fdd0dd
making getcountrycodes at the default values of usestates
abzokhattab 9c798d8
fixing eslint
abzokhattab 7be77e5
remove getCountryCode from Address and Addresspage and add it to the …
abzokhattab 1196f11
minor edit
abzokhattab 48b53e5
adding getCountryCode to MissingPersonalDetailsContent
abzokhattab 41e1bac
using a common hook
abzokhattab a223492
fixing eslint
abzokhattab df2d38e
fixing eslint
abzokhattab 61292b4
Merge remote-tracking branch 'origin/main' into fix/country-picker-mi…
abzokhattab a6f2b60
remvoing hook and using util funciton instead
abzokhattab 400645a
fixing eslint
abzokhattab 97804d3
fixing eslint types
abzokhattab 7f3c67b
fixing eslint
abzokhattab 329141c
fixing types
abzokhattab b335622
adding tests for normalizeCountryCode
abzokhattab 89724b4
fixing cspell
abzokhattab File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import CONST from '@src/CONST'; | ||
| import type {Country} from '@src/CONST'; | ||
| import type {PersonalDetailsForm} from '@src/types/form'; | ||
| import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; | ||
|
|
||
| type AddressType = PersonalDetailsForm | Address | undefined; | ||
|
|
||
| /** | ||
| * Normalizes the address containing a country field by converting country names to country codes. | ||
| * Handles the case where old data has "United States" instead of "US". | ||
| */ | ||
| function normalizeCountryCode(data: AddressType): AddressType { | ||
| if (!data?.country) { | ||
| return data; | ||
| } | ||
|
|
||
| const normalizedCountry = getCountryCode(data.country); | ||
|
|
||
| if (!normalizedCountry) { | ||
| return data; | ||
| } | ||
|
|
||
| return { | ||
| ...data, | ||
| country: normalizedCountry, | ||
| }; | ||
| } | ||
|
|
||
| function getCountryCode(countryValue: string | undefined): Country | undefined { | ||
| for (const [code, name] of Object.entries(CONST.ALL_COUNTRIES)) { | ||
| if (name === countryValue) { | ||
| return code as Country; | ||
| } | ||
| } | ||
|
|
||
| return countryValue as Country | undefined; | ||
| } | ||
|
|
||
| export {normalizeCountryCode, getCountryCode}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| import {getCountryCode, normalizeCountryCode} from '@libs/CountryUtils'; | ||
| import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; | ||
|
|
||
| describe('CountryUtils', () => { | ||
| describe('getCountryCode', () => { | ||
| it('should return the same value if it is already a valid country code', () => { | ||
| expect(getCountryCode('US')).toBe('US'); | ||
| expect(getCountryCode('CA')).toBe('CA'); | ||
| expect(getCountryCode('GB')).toBe('GB'); | ||
| expect(getCountryCode('EG')).toBe('EG'); | ||
| }); | ||
|
|
||
| it('should return the country code when given a country name', () => { | ||
| expect(getCountryCode('United States')).toBe('US'); | ||
| expect(getCountryCode('Canada')).toBe('CA'); | ||
| expect(getCountryCode('United Kingdom')).toBe('GB'); | ||
| expect(getCountryCode('Egypt')).toBe('EG'); | ||
| }); | ||
|
|
||
| it('should return original value for invalid country names or codes', () => { | ||
| expect(getCountryCode('Invalid Country')).toBe('Invalid Country'); | ||
| expect(getCountryCode('XX')).toBe('XX'); | ||
| expect(getCountryCode('123')).toBe('123'); | ||
| expect(getCountryCode('MISSING TRANSLATION')).toBe('MISSING TRANSLATION'); | ||
| }); | ||
|
|
||
| it('should handle edge cases with special characters', () => { | ||
| expect(getCountryCode('Bosnia & Herzegovina')).toBe('BA'); | ||
| }); | ||
|
|
||
| it('should be case sensitive for country names', () => { | ||
| expect(getCountryCode('united states')).toBe('united states'); | ||
| expect(getCountryCode('UNITED STATES')).toBe('UNITED STATES'); | ||
| expect(getCountryCode('United States')).toBe('US'); | ||
| }); | ||
|
|
||
| it('should convert common country names to codes', () => { | ||
| expect(getCountryCode('United States')).toBe('US'); | ||
| }); | ||
|
|
||
| it('should handle multiple country formats correctly', () => { | ||
| const testCases = [ | ||
| {name: 'Afghanistan', code: 'AF'}, | ||
| {name: 'Australia', code: 'AU'}, | ||
| {name: 'Brazil', code: 'BR'}, | ||
| {name: 'China', code: 'CN'}, | ||
| {name: 'France', code: 'FR'}, | ||
| {name: 'Germany', code: 'DE'}, | ||
| {name: 'India', code: 'IN'}, | ||
| {name: 'Japan', code: 'JP'}, | ||
| {name: 'Mexico', code: 'MX'}, | ||
| {name: 'Russia', code: 'RU'}, | ||
| ]; | ||
|
|
||
| testCases.forEach(({name, code}) => { | ||
| expect(getCountryCode(name)).toBe(code); | ||
| expect(getCountryCode(code)).toBe(code); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('normalizeCountryCode', () => { | ||
| it('should return undefined when data is undefined', () => { | ||
| expect(normalizeCountryCode(undefined)).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should return data unchanged when country field is missing', () => { | ||
| const data = {street: '123 Main St', city: 'New York', state: 'NY'}; | ||
| expect(normalizeCountryCode(data)).toEqual(data); | ||
| }); | ||
|
|
||
| it('should return data unchanged when country is undefined', () => { | ||
| const data = {street: '123 Main St', city: 'New York', state: 'NY', country: undefined}; | ||
| expect(normalizeCountryCode(data)).toEqual(data); | ||
| }); | ||
|
|
||
| it('should convert country name to country code', () => { | ||
| const data = {street: '123 Main St', city: 'New York', state: 'NY', country: 'United States'} as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({street: '123 Main St', city: 'New York', state: 'NY', country: 'US'}); | ||
| }); | ||
|
|
||
| it('should preserve country code if already a valid code', () => { | ||
| const data: Address = {street: '456 Oak Ave', city: 'Toronto', state: 'ON', country: 'CA'}; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({street: '456 Oak Ave', city: 'Toronto', state: 'ON', country: 'CA'}); | ||
| }); | ||
|
|
||
| it('should handle multiple country name conversions', () => { | ||
| const testCases = [ | ||
| {input: 'United States', expected: 'US'}, | ||
| {input: 'Canada', expected: 'CA'}, | ||
| {input: 'United Kingdom', expected: 'GB'}, | ||
| {input: 'Germany', expected: 'DE'}, | ||
| {input: 'France', expected: 'FR'}, | ||
| {input: 'Japan', expected: 'JP'}, | ||
| {input: 'Australia', expected: 'AU'}, | ||
| ]; | ||
|
|
||
| testCases.forEach(({input, expected}) => { | ||
| const data = {street: '789 Test St', city: 'Test City', country: input} as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result?.country).toBe(expected); | ||
| }); | ||
| }); | ||
|
|
||
| it('should preserve invalid country values', () => { | ||
| const data = {street: '789 Test St', city: 'Test City', country: 'Invalid Country'} as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({street: '789 Test St', city: 'Test City', country: 'Invalid Country'}); | ||
| }); | ||
|
|
||
| it('should handle special characters in country names', () => { | ||
| const data = {street: '123 Main St', city: 'Sarajevo', country: 'Bosnia & Herzegovina'} as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({street: '123 Main St', city: 'Sarajevo', country: 'BA'}); | ||
| }); | ||
|
|
||
| it('should be case sensitive when normalizing country names', () => { | ||
| const dataLowerCase = {street: '789 Test St', city: 'Test City', country: 'united states'} as unknown as Address; | ||
| const dataUpperCase = {street: '789 Test St', city: 'Test City', country: 'UNITED STATES'} as unknown as Address; | ||
| const dataProperCase = {street: '789 Test St', city: 'Test City', country: 'United States'} as unknown as Address; | ||
|
|
||
| expect(normalizeCountryCode(dataLowerCase)).toEqual({street: '789 Test St', city: 'Test City', country: 'united states'}); | ||
| expect(normalizeCountryCode(dataUpperCase)).toEqual({street: '789 Test St', city: 'Test City', country: 'UNITED STATES'}); | ||
| expect(normalizeCountryCode(dataProperCase)).toEqual({street: '789 Test St', city: 'Test City', country: 'US'}); | ||
| }); | ||
|
|
||
| it('should preserve all other fields in the data object', () => { | ||
| const data = { | ||
| street: '123 Main St', | ||
| city: 'Los Angeles', | ||
| state: 'CA', | ||
| zipCode: '90001', | ||
| country: 'United States', | ||
| } as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({ | ||
| street: '123 Main St', | ||
| city: 'Los Angeles', | ||
| state: 'CA', | ||
| zipCode: '90001', | ||
| country: 'US', | ||
| }); | ||
| }); | ||
|
|
||
| it('should handle MISSING TRANSLATION value', () => { | ||
| const data = {street: '789 Test St', city: 'Test City', country: 'MISSING TRANSLATION'} as unknown as Address; | ||
| const result = normalizeCountryCode(data); | ||
| expect(result).toEqual({street: '789 Test St', city: 'Test City', country: 'MISSING TRANSLATION'}); | ||
| }); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.