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} from '../validateApplicationId'; 12 13jest.mock('node-fetch'); 14jest.mock('../../log'); 15jest.mock('../url'); 16 17function resetOfflineMode() { 18 beforeEach(() => { 19 delete process.env.EXPO_OFFLINE; 20 }); 21 afterAll(() => { 22 delete process.env.EXPO_OFFLINE; 23 }); 24} 25 26describe(validateBundleId, () => { 27 it(`validates`, () => { 28 expect(validateBundleId('bacon')).toBe(true); 29 expect(validateBundleId('...b.a.-c.0.n...')).toBe(true); 30 expect(validateBundleId('.')).toBe(true); 31 expect(validateBundleId('. ..')).toBe(false); 32 expect(validateBundleId('_')).toBe(false); 33 expect(validateBundleId(',')).toBe(false); 34 }); 35}); 36 37describe(validatePackage, () => { 38 it(`validates`, () => { 39 expect(validatePackage('bacon.com.hey')).toBe(true); 40 expect(validatePackage('bacon')).toBe(false); 41 expect(validatePackage('...b.a.-c.0.n...')).toBe(false); 42 expect(validatePackage('.')).toBe(false); 43 expect(validatePackage('. ..')).toBe(false); 44 expect(validatePackage('_')).toBe(false); 45 expect(validatePackage(',')).toBe(false); 46 }); 47}); 48 49describe(getBundleIdWarningInternalAsync, () => { 50 resetOfflineMode(); 51 it(`returns null if the URL cannot be reached`, async () => { 52 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(false); 53 expect(await getBundleIdWarningInternalAsync('bacon')).toBe(null); 54 }); 55 it(`returns null and warns if running in offline-mode`, async () => { 56 process.env.EXPO_OFFLINE = '1'; 57 await expect(getBundleIdWarningInternalAsync('bacon')).resolves.toBe(null); 58 expect(Log.warn).toBeCalledWith(expect.stringMatching(/offline-mode/)); 59 }); 60 it(`returns warning if in use`, async () => { 61 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(true); 62 63 jest.mocked(fetch).mockResolvedValueOnce({ 64 status: 200, 65 json() { 66 return Promise.resolve({ 67 resultCount: 1, 68 results: [ 69 { 70 trackName: 'Pillar Valley', 71 sellerName: 'Evan Bacon', 72 kind: 'software', 73 artistName: 'Evan Bacon', 74 genres: ['Games', 'Entertainment', 'Family', 'Casual'], 75 }, 76 ], 77 }); 78 }, 79 } as any); 80 81 expect( 82 stripAnsi(await getBundleIdWarningInternalAsync('com.bacon.pillarvalley')) 83 ).toMatchInlineSnapshot( 84 `"⚠️ The app Pillar Valley by Evan Bacon is already using com.bacon.pillarvalley"` 85 ); 86 }); 87}); 88 89describe(getPackageNameWarningInternalAsync, () => { 90 resetOfflineMode(); 91 92 it(`returns null if the URL cannot be reached`, async () => { 93 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(false); 94 expect(await getPackageNameWarningInternalAsync('bacon')).toBe(null); 95 }); 96 it(`returns null and warns if running in offline-mode`, async () => { 97 process.env.EXPO_OFFLINE = '1'; 98 expect(await getPackageNameWarningInternalAsync('123')).toBe(null); 99 expect(Log.warn).toBeCalledWith(expect.stringMatching(/offline-mode/)); 100 }); 101 it(`returns warning if in use`, async () => { 102 jest.mocked(isUrlAvailableAsync).mockResolvedValueOnce(true); 103 jest.mocked(fetch).mockResolvedValueOnce({ 104 status: 200, 105 } as any); 106 107 expect( 108 stripAnsi(await getPackageNameWarningInternalAsync('com.bacon.pillarvalley')) 109 ).toMatchInlineSnapshot( 110 `"⚠️ The package com.bacon.pillarvalley is already in use. Learn more: https://play.google.com/store/apps/details?id=com.bacon.pillarvalley"` 111 ); 112 }); 113}); 114