1import { vol } from 'memfs'; 2 3import { getConfig, getProjectConfigDescriptionWithPaths } from '../Config'; 4 5jest.mock('fs'); 6 7describe(getProjectConfigDescriptionWithPaths, () => { 8 it(`describes a project using both a static and dynamic config`, () => { 9 const message = getProjectConfigDescriptionWithPaths('/', { 10 dynamicConfigPath: '/app.config.js', 11 staticConfigPath: '/app.config.json', 12 }); 13 expect(message).toMatch(`app.config.js`); 14 expect(message).toMatch(`app.config.json`); 15 }); 16 it(`describes a project using only a static config`, () => { 17 const message = getProjectConfigDescriptionWithPaths('/', { 18 dynamicConfigPath: null, 19 staticConfigPath: '/app.json', 20 }); 21 expect(message).toMatch(`app.json`); 22 }); 23 it(`describes a project using only a dynamic config`, () => { 24 const message = getProjectConfigDescriptionWithPaths('/', { 25 dynamicConfigPath: '/app.config.ts', 26 staticConfigPath: null, 27 }); 28 expect(message).toMatch(`app.config.ts`); 29 }); 30 it(`describes a project with no configs using a default value`, () => { 31 const message = getProjectConfigDescriptionWithPaths('/', { 32 dynamicConfigPath: null, 33 staticConfigPath: null, 34 }); 35 expect(message).toBe('app.json'); 36 }); 37}); 38 39describe('getConfig public config', () => { 40 const appJsonWithPrivateData = { 41 name: 'testing 123', 42 version: '0.1.0', 43 slug: 'testing-123', 44 sdkVersion: '100.0.0', 45 hooks: { 46 postPublish: [], 47 }, 48 android: { 49 config: { 50 googleMaps: { 51 apiKey: 'test-key', 52 }, 53 }, 54 versionCode: 1, 55 }, 56 ios: { 57 config: { 58 googleMapsApiKey: 'test-key', 59 }, 60 buildNumber: '1.0', 61 }, 62 }; 63 64 const appJsonNoPrivateData = { 65 name: 'testing 123', 66 version: '0.1.0', 67 slug: 'testing-123', 68 sdkVersion: '100.0.0', 69 ios: { 70 buildNumber: '1.0', 71 }, 72 }; 73 74 beforeAll(() => { 75 const packageJson = JSON.stringify( 76 { 77 name: 'testing123', 78 version: '0.1.0', 79 description: 'fake description', 80 main: 'index.js', 81 }, 82 null, 83 2 84 ); 85 86 vol.fromJSON({ 87 '/private-data/package.json': packageJson, 88 '/private-data/app.json': JSON.stringify({ expo: appJsonWithPrivateData }), 89 '/no-private-data/package.json': packageJson, 90 '/no-private-data/app.json': JSON.stringify({ expo: appJsonNoPrivateData }), 91 }); 92 }); 93 94 afterAll(() => vol.reset()); 95 96 it('removes only private data from the config', () => { 97 const { exp } = getConfig('/private-data', { isPublicConfig: true }); 98 99 expect(exp.hooks).toBeUndefined(); 100 101 expect(exp.ios).toBeDefined(); 102 expect(exp.ios!.buildNumber).toEqual(appJsonWithPrivateData.ios.buildNumber); 103 expect(exp.ios!.config).toBeUndefined(); 104 105 expect(exp.android).toBeDefined(); 106 expect(exp.android!.versionCode).toEqual(appJsonWithPrivateData.android.versionCode); 107 expect(exp.android!.config).toBeUndefined(); 108 expect(exp._internal).toBeUndefined(); 109 }); 110 111 it('does not remove properties from a config with no private data', () => { 112 const { exp } = getConfig('/no-private-data', { isPublicConfig: true }); 113 expect(exp).toMatchObject(appJsonNoPrivateData); 114 }); 115}); 116 117describe('readConfigJson', () => { 118 describe('sdkVersion', () => { 119 beforeAll(() => { 120 const packageJson = JSON.stringify( 121 { 122 name: 'testing123', 123 version: '0.1.0', 124 description: 'fake description', 125 main: 'index.js', 126 }, 127 null, 128 2 129 ); 130 131 const appJson = { 132 name: 'testing 123', 133 version: '0.1.0', 134 slug: 'testing-123', 135 sdkVersion: '100.0.0', 136 }; 137 138 const expoPackageJson = JSON.stringify({ 139 name: 'expo', 140 version: '650.x.x', 141 }); 142 143 vol.fromJSON({ 144 '/from-config/package.json': packageJson, 145 '/from-config/app.json': JSON.stringify({ expo: appJson }), 146 '/from-config/node_modules/expo/package.json': expoPackageJson, 147 148 '/from-package/package.json': packageJson, 149 '/from-package/app.json': JSON.stringify({ expo: { ...appJson, sdkVersion: undefined } }), 150 '/from-package/node_modules/expo/package.json': expoPackageJson, 151 152 '/no-version/package.json': packageJson, 153 '/no-version/app.json': JSON.stringify({ expo: { ...appJson, sdkVersion: undefined } }), 154 }); 155 }); 156 afterAll(() => vol.reset()); 157 158 it('reads the SDK version from the config', () => { 159 const { exp } = getConfig('/from-config'); 160 expect(exp.sdkVersion).toBe('100.0.0'); 161 }); 162 163 it('reads the SDK version from the installed version of expo', () => { 164 const { exp } = getConfig('/from-package'); 165 expect(exp.sdkVersion).toBe('650.0.0'); 166 }); 167 }); 168 169 describe('validation', () => { 170 beforeAll(() => { 171 const packageJson = JSON.stringify({ 172 name: 'testing123', 173 version: '0.1.0', 174 main: 'index.js', 175 }); 176 177 const expoPackageJson = JSON.stringify({ 178 name: 'expo', 179 version: '650.x.x', 180 }); 181 182 vol.fromJSON({ 183 '/no-config/package.json': packageJson, 184 '/no-config/node_modules/expo/package.json': expoPackageJson, 185 186 '/no-package/package.json': packageJson, 187 }); 188 }); 189 afterAll(() => vol.reset()); 190 191 it(`can skip throwing when the app.json is missing and expo isn't installed`, () => { 192 const { exp, pkg } = getConfig('/no-package', { skipSDKVersionRequirement: true }); 193 expect(exp.name).toBe(pkg.name); 194 expect(exp.description).toBe(pkg.description); 195 }); 196 197 it(`will not throw if the app.json is missing`, () => { 198 // No config is required for new method 199 expect(() => getConfig('/no-config')).not.toThrow(); 200 }); 201 202 it(`will not throw if the expo package is missing when skipSDKVersionRequirement is enabled`, () => { 203 expect(() => getConfig('/no-package', { skipSDKVersionRequirement: false })).toThrow( 204 /Cannot determine which native SDK version your project uses/ 205 ); 206 }); 207 }); 208}); 209