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