1import fetch from 'node-fetch'; 2 3import { Log } from '../../log'; 4import { stripAnsi } from '../ansi'; 5import { isUrlAvailableAsync } from '../url'; 6import { 7 getBundleIdWarningInternalAsync, 8 getPackageNameWarningInternalAsync, 9 validateBundleId, 10 validatePackage, 11 validatePackageWithWarning, 12} from '../validateApplicationId'; 13 14jest.mock('node-fetch'); 15jest.mock('../../log'); 16jest.mock('../url'); 17 18function resetOfflineMode() { 19 beforeEach(() => { 20 delete process.env.EXPO_OFFLINE; 21 }); 22 afterAll(() => { 23 delete process.env.EXPO_OFFLINE; 24 }); 25} 26 27describe(validateBundleId, () => { 28 it(`validates`, () => { 29 expect(validateBundleId('bacon')).toBe(true); 30 expect(validateBundleId('...b.a.-c.0.n...')).toBe(true); 31 expect(validateBundleId('.')).toBe(true); 32 expect(validateBundleId('. ..')).toBe(false); 33 expect(validateBundleId('_')).toBe(false); 34 expect(validateBundleId(',')).toBe(false); 35 }); 36}); 37 38describe(validatePackageWithWarning, () => { 39 it(`validates with warnings`, () => { 40 expect(validatePackageWithWarning('bacon.native')).toEqual( 41 `"native" is a reserved Java keyword.` 42 ); 43 expect(validatePackageWithWarning('bacon')).toEqual( 44 'Package name must contain more than one segment, separated by ".", e.g. com.bacon' 45 ); 46 expect(validatePackageWithWarning(',')).toEqual( 47 `Package name must contain more than one segment, separated by ".", e.g. com.,` 48 ); 49 }); 50}); 51describe(validatePackage, () => { 52 it(`validates`, () => { 53 expect(validatePackage('bacon.com.hey')).toBe(true); 54 expect(validatePackage('bacon')).toBe(false); 55 expect(validatePackage('com.native')).toBe(false); 56 expect(validatePackage('native.android')).toBe(false); 57 expect(validatePackage('...b.a.-c.0.n...')).toBe(false); 58 expect(validatePackage('.')).toBe(false); 59 expect(validatePackage('. ..')).toBe(false); 60 expect(validatePackage('_')).toBe(false); 61 expect(validatePackage(',')).toBe(false); 62 }); 63 it(`prevents using reserved java keywords`, () => { 64 expect(validatePackage('bacon.native.com')).toBe(false); 65 expect(validatePackage('byte')).toBe(false); 66 }); 67}); 68 69describe(getBundleIdWarningInternalAsync, () => { 70 resetOfflineMode(); 71 it(`returns null if the URL cannot be reached`, async () => { 72 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(false); 73 expect(await getBundleIdWarningInternalAsync('bacon')).toBe(null); 74 }); 75 it(`returns null and warns if running in offline-mode`, async () => { 76 process.env.EXPO_OFFLINE = '1'; 77 await expect(getBundleIdWarningInternalAsync('bacon')).resolves.toBe(null); 78 expect(Log.warn).toBeCalledWith(expect.stringMatching(/offline-mode/)); 79 }); 80 it(`returns warning if in use`, async () => { 81 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(true); 82 83 jest.mocked(fetch).mockResolvedValueOnce({ 84 status: 200, 85 json() { 86 return Promise.resolve({ 87 resultCount: 1, 88 results: [ 89 { 90 trackName: 'Pillar Valley', 91 sellerName: 'Evan Bacon', 92 kind: 'software', 93 artistName: 'Evan Bacon', 94 genres: ['Games', 'Entertainment', 'Family', 'Casual'], 95 }, 96 ], 97 }); 98 }, 99 } as any); 100 101 expect( 102 stripAnsi(await getBundleIdWarningInternalAsync('com.bacon.pillarvalley')) 103 ).toMatchInlineSnapshot( 104 `"⚠️ The app Pillar Valley by Evan Bacon is already using com.bacon.pillarvalley"` 105 ); 106 }); 107}); 108 109describe(getPackageNameWarningInternalAsync, () => { 110 resetOfflineMode(); 111 112 it(`returns null if the URL cannot be reached`, async () => { 113 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(false); 114 expect(await getPackageNameWarningInternalAsync('bacon')).toBe(null); 115 }); 116 it(`returns null and warns if running in offline-mode`, async () => { 117 process.env.EXPO_OFFLINE = '1'; 118 expect(await getPackageNameWarningInternalAsync('123')).toBe(null); 119 expect(Log.warn).toBeCalledWith(expect.stringMatching(/offline-mode/)); 120 }); 121 it(`returns warning if in use`, async () => { 122 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(true); 123 jest.mocked(fetch).mockResolvedValueOnce({ 124 status: 200, 125 } as any); 126 127 expect( 128 stripAnsi(await getPackageNameWarningInternalAsync('com.bacon.pillarvalley')) 129 ).toMatchInlineSnapshot( 130 `"⚠️ The package com.bacon.pillarvalley is already in use. Learn more: https://play.google.com/store/apps/details?id=com.bacon.pillarvalley"` 131 ); 132 }); 133}); 134