1import * as fs from 'fs'; 2import { vol } from 'memfs'; 3import * as path from 'path'; 4 5import * as WarningAggregator from '../../utils/warnings'; 6import { getLocales, setLocalesAsync } from '../Locales'; 7import { getPbxproj } from '../utils/Xcodeproj'; 8import { getDirFromFS } from './utils/getDirFromFS'; 9 10const fsReal = jest.requireActual('fs') as typeof fs; 11 12jest.mock('fs'); 13jest.mock('../../utils/warnings'); 14 15describe('iOS Locales', () => { 16 it(`returns null if no values are provided`, () => { 17 expect(getLocales({})).toBeNull(); 18 }); 19 20 it(`returns the locales object`, () => { 21 expect( 22 getLocales({ 23 locales: {}, 24 }) 25 ).toStrictEqual({}); 26 }); 27}); 28 29describe('e2e: iOS locales', () => { 30 const projectRoot = '/app'; 31 beforeAll(async () => { 32 vol.fromJSON( 33 { 34 'ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync( 35 path.join(__dirname, 'fixtures/project.pbxproj'), 36 'utf-8' 37 ), 38 'ios/testproject/AppDelegate.m': '', 39 'lang/fr.json': JSON.stringify({ 40 CFBundleDisplayName: 'french-name', 41 }), 42 }, 43 projectRoot 44 ); 45 }); 46 47 afterAll(() => { 48 vol.reset(); 49 }); 50 51 it('writes all the image files expected', async () => { 52 let project = getPbxproj(projectRoot); 53 54 project = await setLocalesAsync( 55 { 56 locales: { 57 fr: 'lang/fr.json', 58 // doesn't exist 59 xx: 'lang/xx.json', 60 // partially support inlining the JSON so our Expo Config type doesn't conflict with the resolved manifest type. 61 es: { CFBundleDisplayName: 'spanish-name' }, 62 }, 63 }, 64 { project, projectRoot } 65 ); 66 // Sync the Xcode project with the changes. 67 fs.writeFileSync(project.filepath, project.writeSync()); 68 69 const after = getDirFromFS(vol.toJSON(), projectRoot); 70 const locales = Object.keys(after).filter((value) => value.endsWith('InfoPlist.strings')); 71 72 expect(locales.length).toBe(2); 73 expect(after[locales[0]]).toMatchSnapshot(); 74 // Test that the inlined locale is resolved. 75 expect(after[locales[1]]).toMatch(/spanish-name/); 76 // Test a warning is thrown for an invalid locale JSON file. 77 expect(WarningAggregator.addWarningIOS).toHaveBeenCalledWith( 78 'locales.xx', 79 'Failed to parse JSON of locale file for language: xx', 80 'https://docs.expo.dev/distribution/app-stores/#localizing-your-ios-app' 81 ); 82 }); 83}); 84