1import plist from '@expo/plist'; 2import * as fs from 'fs'; 3import { vol } from 'memfs'; 4import * as path from 'path'; 5 6import rnFixture from '../../plugins/__tests__/fixtures/react-native-project'; 7import { 8 ensureApplicationTargetEntitlementsFileConfigured, 9 getEntitlementsPath, 10} from '../Entitlements'; 11 12const fsReal = jest.requireActual('fs') as typeof fs; 13 14jest.mock('fs'); 15 16const exampleEntitlements = `<?xml version="0.0" encoding="UTF-8"?> 17<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 18<plist version="1.0"> 19<dict> 20 <key>special</key> 21 <true/> 22</dict> 23</plist>`; 24 25describe(ensureApplicationTargetEntitlementsFileConfigured, () => { 26 const projectRoot = '/app'; 27 28 afterEach(() => { 29 vol.reset(); 30 }); 31 32 it('creates a new entitlements file when none exists', async () => { 33 vol.fromJSON(rnFixture, projectRoot); 34 const entitlementsPathBefore = getEntitlementsPath(projectRoot); 35 ensureApplicationTargetEntitlementsFileConfigured(projectRoot); 36 const entitlementsPath = getEntitlementsPath(projectRoot); 37 expect(entitlementsPathBefore).toBeNull(); 38 expect(entitlementsPath).toBe('/app/ios/HelloWorld/HelloWorld.entitlements'); 39 40 // New file has the contents of the old entitlements file 41 const data = plist.parse(await fs.promises.readFile(entitlementsPath!, 'utf8')); 42 expect(data).toStrictEqual({ 43 // No entitlements enabled by default 44 }); 45 }); 46 47 it('creates a new entitlements file if file in XCBuildConfiguration does not exists', async () => { 48 vol.fromJSON( 49 { 50 'ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync( 51 path.join(__dirname, 'fixtures/project-with-entitlements.pbxproj'), 52 'utf-8' 53 ), 54 'ios/testproject/AppDelegate.m': '', 55 }, 56 projectRoot 57 ); 58 ensureApplicationTargetEntitlementsFileConfigured(projectRoot); 59 const entitlementsPath = getEntitlementsPath(projectRoot); 60 expect(entitlementsPath).toBe('/app/ios/testproject/testproject.entitlements'); 61 62 // New file has the contents of the old entitlements file 63 const data = plist.parse(await fs.promises.readFile(entitlementsPath, 'utf8')); 64 expect(data).toStrictEqual({}); 65 }); 66 67 it('does not create any entitlements files if it already exists', async () => { 68 vol.fromJSON( 69 { 70 'ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync( 71 path.join(__dirname, 'fixtures/project-with-entitlements.pbxproj'), 72 'utf-8' 73 ), 74 'ios/testapp/example.entitlements': exampleEntitlements, 75 'ios/testproject/AppDelegate.m': '', 76 }, 77 projectRoot 78 ); 79 ensureApplicationTargetEntitlementsFileConfigured(projectRoot); 80 const entitlementsPath = getEntitlementsPath(projectRoot); 81 expect(entitlementsPath).toBe('/app/ios/testapp/example.entitlements'); 82 83 // New file has the contents of the old entitlements file 84 const data = plist.parse(await fs.promises.readFile(entitlementsPath, 'utf8')); 85 expect(data).toStrictEqual({ special: true }); 86 87 // entitlement file in default location does not exist 88 expect(fs.existsSync('/app/ios/testproject/testproject.entitlements')).toBe(false); 89 }); 90}); 91 92describe(getEntitlementsPath, () => { 93 const projectRoot = '/app'; 94 95 afterEach(() => { 96 vol.reset(); 97 }); 98 99 it('returns null if CODE_SIGN_ENTITLEMENTS is not specified', async () => { 100 vol.fromJSON( 101 { 102 'ios/testproject.xcodeproj/project.pbxproj': 103 rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'], 104 'ios/testproject/AppDelegate.m': '', 105 }, 106 projectRoot 107 ); 108 109 const entitlementsPath = getEntitlementsPath(projectRoot); 110 expect(entitlementsPath).toBeNull(); 111 }); 112 it('returns path if CODE_SIGN_ENTITLEMENTS is specified and file exists', async () => { 113 vol.fromJSON( 114 { 115 'ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync( 116 path.join(__dirname, 'fixtures/project-with-entitlements.pbxproj'), 117 'utf-8' 118 ), 119 'ios/testapp/example.entitlements': exampleEntitlements, 120 'ios/testproject/AppDelegate.m': '', 121 }, 122 projectRoot 123 ); 124 125 const entitlementsPath = getEntitlementsPath(projectRoot); 126 expect(entitlementsPath).toBe('/app/ios/testapp/example.entitlements'); 127 }); 128}); 129