1import { resolve } from 'path'; 2 3import { getMainActivity, readAndroidManifestAsync } from '../Manifest'; 4import { 5 appendScheme, 6 ensureManifestHasValidIntentFilter, 7 getScheme, 8 getSchemesFromManifest, 9 hasScheme, 10 removeScheme, 11 setScheme, 12} from '../Scheme'; 13 14const fixturesPath = resolve(__dirname, 'fixtures'); 15const sampleManifestPath = resolve(fixturesPath, 'react-native-AndroidManifest.xml'); 16const sampleManifestWithHostPath = resolve( 17 fixturesPath, 18 'react-native-AndroidManifest-with-host.xml' 19); 20 21describe('scheme', () => { 22 it(`returns empty array if no scheme is provided`, () => { 23 expect(getScheme({})).toStrictEqual([]); 24 }); 25 26 it(`returns the scheme if provided`, () => { 27 expect(getScheme({ scheme: 'myapp' })).toStrictEqual(['myapp']); 28 expect(getScheme({ scheme: ['other', 'myapp'] })).toStrictEqual(['other', 'myapp']); 29 expect( 30 getScheme({ 31 scheme: ['other', 'myapp', null], 32 }) 33 ).toStrictEqual(['other', 'myapp']); 34 }); 35 36 it('does not add scheme if none provided', async () => { 37 let androidManifestJson = await readAndroidManifestAsync(sampleManifestPath); 38 androidManifestJson = await setScheme({}, androidManifestJson); 39 40 expect(androidManifestJson).toEqual(androidManifestJson); 41 }); 42 43 it('adds scheme to android manifest', async () => { 44 let androidManifestJson = await readAndroidManifestAsync(sampleManifestPath); 45 androidManifestJson = await setScheme( 46 { 47 scheme: 'myapp', 48 android: { 49 // @ts-ignore 50 scheme: ['android-only'], 51 package: 'com.demo.value', 52 }, 53 ios: { scheme: 'ios-only' }, 54 }, 55 androidManifestJson 56 ); 57 58 const mainActivity = getMainActivity(androidManifestJson); 59 const intentFilters = mainActivity['intent-filter']; 60 61 const schemeIntent = []; 62 63 for (const intent of intentFilters) { 64 if ('data' in intent) { 65 for (const dataFilter of intent.data) { 66 const possibleScheme = dataFilter.$['android:scheme']; 67 if (possibleScheme) { 68 schemeIntent.push(possibleScheme); 69 } 70 } 71 } 72 } 73 74 expect(schemeIntent).toStrictEqual(['myapp', 'android-only', 'com.demo.value']); 75 }); 76}); 77 78function removeSingleTaskFromActivities(manifest) { 79 for (const application of manifest.manifest.application) { 80 for (const activity of application.activity) { 81 if (activity.$['android:launchMode'] === 'singleTask') { 82 delete activity.$['android:launchMode']; 83 } 84 } 85 } 86 87 return manifest; 88} 89 90describe('Schemes', () => { 91 it(`ensure manifest has valid intent filter added`, async () => { 92 const manifest = await readAndroidManifestAsync(sampleManifestPath); 93 const manifestHasValidIntentFilter = ensureManifestHasValidIntentFilter(manifest); 94 expect(manifestHasValidIntentFilter).toBe(true); 95 }); 96 97 it(`detect if no singleTask Activity exists`, async () => { 98 const manifest = await readAndroidManifestAsync(sampleManifestPath); 99 removeSingleTaskFromActivities(manifest); 100 101 expect(ensureManifestHasValidIntentFilter(manifest)).toBe(false); 102 }); 103 104 it(`adds and removes a new scheme`, async () => { 105 const manifest = await readAndroidManifestAsync(sampleManifestPath); 106 ensureManifestHasValidIntentFilter(manifest); 107 108 const modifiedManifest = appendScheme('myapp.test', manifest); 109 const schemes = getSchemesFromManifest(modifiedManifest); 110 expect(schemes).toContain('myapp.test'); 111 const removedManifest = removeScheme('myapp.test', manifest); 112 expect(getSchemesFromManifest(removedManifest)).not.toContain('myapp.test'); 113 }); 114 115 it(`get all schemes for the host`, async () => { 116 const manifest = await readAndroidManifestAsync(sampleManifestWithHostPath); 117 ensureManifestHasValidIntentFilter(manifest); 118 expect(hasScheme('longestschemewiththehost', manifest)).toBe(true); 119 120 const modifiedManifest = appendScheme('myapp.test', manifest); 121 let schemes = getSchemesFromManifest(modifiedManifest, 'any-host'); 122 expect(schemes).toContain('myapp.test'); 123 expect(schemes).not.toContain('longestschemewiththehost'); 124 125 schemes = getSchemesFromManifest(modifiedManifest, 'expo-development-client'); 126 expect(schemes).toContain('myapp.test'); 127 expect(schemes).toContain('longestschemewiththehost'); 128 }); 129 130 it(`detect when a duplicate might be added`, async () => { 131 const manifest = await readAndroidManifestAsync(sampleManifestPath); 132 ensureManifestHasValidIntentFilter(manifest); 133 134 const modifiedManifest = appendScheme('myapp.test', manifest); 135 expect(hasScheme('myapp.test', modifiedManifest)).toBe(true); 136 }); 137 138 it(`detect a non-existent scheme`, async () => { 139 const manifest = await readAndroidManifestAsync(sampleManifestPath); 140 141 expect(hasScheme('myapp.test', manifest)).toBe(false); 142 }); 143}); 144