1*6fb32dddSKeith Kurakimport { getConfig } from '@expo/config'; 2*6fb32dddSKeith Kurak 3fa5bc561SWill Schurmanimport { asMock } from '../../__tests__/asMock'; 4c94ad8a2SEvan Baconimport { Log } from '../../log'; 5c94ad8a2SEvan Baconimport { 6c94ad8a2SEvan Bacon getVersionedDependenciesAsync, 7c94ad8a2SEvan Bacon logIncorrectDependencies, 8c94ad8a2SEvan Bacon} from '../../start/doctor/dependencies/validateDependenciesVersions'; 9c94ad8a2SEvan Baconimport { confirmAsync } from '../../utils/prompts'; 10c94ad8a2SEvan Baconimport { checkPackagesAsync } from '../checkPackages'; 118d3f3824SCedric van Puttenimport { fixPackagesAsync } from '../installAsync'; 12c94ad8a2SEvan Bacon 13c94ad8a2SEvan Baconjest.mock('../../log'); 14c94ad8a2SEvan Bacon 15c94ad8a2SEvan Baconjest.mock('../../utils/prompts'); 16c94ad8a2SEvan Bacon 17c94ad8a2SEvan Baconjest.mock('../installAsync', () => ({ 188d3f3824SCedric van Putten fixPackagesAsync: jest.fn(), 19c94ad8a2SEvan Bacon})); 20c94ad8a2SEvan Bacon 21c94ad8a2SEvan Baconjest.mock('../../start/doctor/dependencies/validateDependenciesVersions', () => ({ 22c94ad8a2SEvan Bacon getVersionedDependenciesAsync: jest.fn(), 23c94ad8a2SEvan Bacon logIncorrectDependencies: jest.fn(), 24c94ad8a2SEvan Bacon})); 25c94ad8a2SEvan Bacon 26c94ad8a2SEvan Baconjest.mock('@expo/config', () => ({ 27c94ad8a2SEvan Bacon getProjectConfigDescriptionWithPaths: jest.fn(), 28c94ad8a2SEvan Bacon getConfig: jest.fn(() => ({ 29c94ad8a2SEvan Bacon pkg: {}, 30c94ad8a2SEvan Bacon exp: { 31c94ad8a2SEvan Bacon sdkVersion: '45.0.0', 32c94ad8a2SEvan Bacon name: 'my-app', 33c94ad8a2SEvan Bacon slug: 'my-app', 34c94ad8a2SEvan Bacon }, 35c94ad8a2SEvan Bacon })), 36c94ad8a2SEvan Bacon})); 37c94ad8a2SEvan Bacon 38c94ad8a2SEvan Bacondescribe(checkPackagesAsync, () => { 39c94ad8a2SEvan Bacon it(`checks packages and exits when packages are invalid`, async () => { 40c94ad8a2SEvan Bacon asMock(confirmAsync).mockResolvedValueOnce(false); 41c94ad8a2SEvan Bacon asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([ 42c94ad8a2SEvan Bacon { 43c94ad8a2SEvan Bacon packageName: 'react-native', 448d3f3824SCedric van Putten packageType: 'dependencies', 45c94ad8a2SEvan Bacon expectedVersionOrRange: '^1.0.0', 46c94ad8a2SEvan Bacon actualVersion: '0.69.0', 47c94ad8a2SEvan Bacon }, 48c94ad8a2SEvan Bacon ]); 49c94ad8a2SEvan Bacon await expect( 50c94ad8a2SEvan Bacon checkPackagesAsync('/', { 51c94ad8a2SEvan Bacon packages: ['react-native'], 52c94ad8a2SEvan Bacon options: { fix: false }, 53c94ad8a2SEvan Bacon // @ts-expect-error 54c94ad8a2SEvan Bacon packageManager: {}, 55c94ad8a2SEvan Bacon packageManagerArguments: [], 56c94ad8a2SEvan Bacon }) 57c94ad8a2SEvan Bacon ).rejects.toThrowError(/EXIT/); 58c94ad8a2SEvan Bacon 59c94ad8a2SEvan Bacon expect(logIncorrectDependencies).toBeCalledTimes(1); 60c94ad8a2SEvan Bacon 61c94ad8a2SEvan Bacon expect(Log.exit).toBeCalledWith( 62c94ad8a2SEvan Bacon // Because of ansi 63c94ad8a2SEvan Bacon expect.stringContaining('Found outdated dependencies'), 64c94ad8a2SEvan Bacon 1 65c94ad8a2SEvan Bacon ); 66c94ad8a2SEvan Bacon }); 67c94ad8a2SEvan Bacon 68*6fb32dddSKeith Kurak it(`notifies when dependencies are on exclude list`, async () => { 69*6fb32dddSKeith Kurak asMock(confirmAsync).mockResolvedValueOnce(false); 70*6fb32dddSKeith Kurak // @ts-expect-error 71*6fb32dddSKeith Kurak asMock(getConfig).mockReturnValueOnce({ 72*6fb32dddSKeith Kurak pkg: { 73*6fb32dddSKeith Kurak expo: { 74*6fb32dddSKeith Kurak install: { 75*6fb32dddSKeith Kurak exclude: ['expo-av', 'expo-blur'], 76*6fb32dddSKeith Kurak }, 77*6fb32dddSKeith Kurak }, 78*6fb32dddSKeith Kurak }, 79*6fb32dddSKeith Kurak exp: { 80*6fb32dddSKeith Kurak sdkVersion: '45.0.0', 81*6fb32dddSKeith Kurak name: 'my-app', 82*6fb32dddSKeith Kurak slug: 'my-app', 83*6fb32dddSKeith Kurak }, 84*6fb32dddSKeith Kurak }); 85*6fb32dddSKeith Kurak asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([ 86*6fb32dddSKeith Kurak { 87*6fb32dddSKeith Kurak packageName: 'expo-av', 88*6fb32dddSKeith Kurak packageType: 'dependencies', 89*6fb32dddSKeith Kurak expectedVersionOrRange: '^2.0.0', 90*6fb32dddSKeith Kurak actualVersion: '1.0.0', 91*6fb32dddSKeith Kurak }, 92*6fb32dddSKeith Kurak ]); 93*6fb32dddSKeith Kurak await checkPackagesAsync('/', { 94*6fb32dddSKeith Kurak packages: ['expo-av'], 95*6fb32dddSKeith Kurak options: { fix: true }, 96*6fb32dddSKeith Kurak // @ts-expect-error 97*6fb32dddSKeith Kurak packageManager: {}, 98*6fb32dddSKeith Kurak packageManagerArguments: [], 99*6fb32dddSKeith Kurak }); 100*6fb32dddSKeith Kurak 101*6fb32dddSKeith Kurak expect(Log.log).toBeCalledWith( 102*6fb32dddSKeith Kurak expect.stringContaining('Skipped fixing dependencies: expo-av and expo-blur') 103*6fb32dddSKeith Kurak ); 104*6fb32dddSKeith Kurak }); 105*6fb32dddSKeith Kurak 106c94ad8a2SEvan Bacon it(`checks packages and exits with zero if all are valid`, async () => { 107c94ad8a2SEvan Bacon asMock(confirmAsync).mockResolvedValueOnce(false); 108c94ad8a2SEvan Bacon asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([]); 109c94ad8a2SEvan Bacon await expect( 110c94ad8a2SEvan Bacon checkPackagesAsync('/', { 111c94ad8a2SEvan Bacon packages: ['react-native'], 112c94ad8a2SEvan Bacon options: { fix: false }, 113c94ad8a2SEvan Bacon // @ts-expect-error 114c94ad8a2SEvan Bacon packageManager: {}, 115c94ad8a2SEvan Bacon packageManagerArguments: [], 116c94ad8a2SEvan Bacon }) 117c94ad8a2SEvan Bacon ).rejects.toThrowError(/EXIT/); 118c94ad8a2SEvan Bacon 119c94ad8a2SEvan Bacon expect(logIncorrectDependencies).toBeCalledTimes(0); 120c94ad8a2SEvan Bacon 121c94ad8a2SEvan Bacon expect(Log.exit).toBeCalledWith( 122c94ad8a2SEvan Bacon // Because of ansi 123c94ad8a2SEvan Bacon expect.stringContaining('Dependencies are up to date'), 124c94ad8a2SEvan Bacon 0 125c94ad8a2SEvan Bacon ); 126c94ad8a2SEvan Bacon }); 127c94ad8a2SEvan Bacon 128c94ad8a2SEvan Bacon it(`fixes invalid packages`, async () => { 1298d3f3824SCedric van Putten const issues: Awaited<ReturnType<typeof getVersionedDependenciesAsync>> = [ 130c94ad8a2SEvan Bacon { 131c94ad8a2SEvan Bacon packageName: 'react-native', 1328d3f3824SCedric van Putten packageType: 'dependencies', 133c94ad8a2SEvan Bacon expectedVersionOrRange: '^1.0.0', 134c94ad8a2SEvan Bacon actualVersion: '0.69.0', 135c94ad8a2SEvan Bacon }, 136c94ad8a2SEvan Bacon { 137c94ad8a2SEvan Bacon packageName: 'expo', 1388d3f3824SCedric van Putten packageType: 'dependencies', 139c94ad8a2SEvan Bacon expectedVersionOrRange: '^1.0.0', 140c94ad8a2SEvan Bacon actualVersion: '0.69.0', 141c94ad8a2SEvan Bacon }, 1428d3f3824SCedric van Putten ]; 1438d3f3824SCedric van Putten 1448d3f3824SCedric van Putten asMock(getVersionedDependenciesAsync).mockResolvedValueOnce(issues); 145c94ad8a2SEvan Bacon 146c94ad8a2SEvan Bacon await checkPackagesAsync('/', { 147c94ad8a2SEvan Bacon packages: ['react-native', 'expo'], 148c94ad8a2SEvan Bacon options: { fix: true }, 149c94ad8a2SEvan Bacon // @ts-expect-error 150c94ad8a2SEvan Bacon packageManager: {}, 151c94ad8a2SEvan Bacon packageManagerArguments: [], 152c94ad8a2SEvan Bacon }); 153c94ad8a2SEvan Bacon 1548d3f3824SCedric van Putten expect(fixPackagesAsync).toBeCalledWith('/', { 155c94ad8a2SEvan Bacon packageManager: {}, 156c94ad8a2SEvan Bacon packageManagerArguments: [], 1578d3f3824SCedric van Putten packages: issues, 158c94ad8a2SEvan Bacon sdkVersion: '45.0.0', 159c94ad8a2SEvan Bacon }); 160c94ad8a2SEvan Bacon expect(logIncorrectDependencies).toBeCalledTimes(1); 161c94ad8a2SEvan Bacon }); 162c94ad8a2SEvan Bacon}); 163