1import { asMock } from '../../__tests__/asMock';
2import { Log } from '../../log';
3import {
4  getVersionedDependenciesAsync,
5  logIncorrectDependencies,
6} from '../../start/doctor/dependencies/validateDependenciesVersions';
7import { confirmAsync } from '../../utils/prompts';
8import { checkPackagesAsync } from '../checkPackages';
9import { installPackagesAsync } from '../installAsync';
10
11jest.mock('../../log');
12
13jest.mock('../../utils/prompts');
14
15jest.mock('../installAsync', () => ({
16  installPackagesAsync: jest.fn(),
17}));
18
19jest.mock('../../start/doctor/dependencies/validateDependenciesVersions', () => ({
20  getVersionedDependenciesAsync: jest.fn(),
21  logIncorrectDependencies: jest.fn(),
22}));
23
24jest.mock('@expo/config', () => ({
25  getProjectConfigDescriptionWithPaths: jest.fn(),
26  getConfig: jest.fn(() => ({
27    pkg: {},
28    exp: {
29      sdkVersion: '45.0.0',
30      name: 'my-app',
31      slug: 'my-app',
32    },
33  })),
34}));
35
36describe(checkPackagesAsync, () => {
37  it(`checks packages and exits when packages are invalid`, async () => {
38    asMock(confirmAsync).mockResolvedValueOnce(false);
39    asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([
40      {
41        packageName: 'react-native',
42        expectedVersionOrRange: '^1.0.0',
43        actualVersion: '0.69.0',
44      },
45    ]);
46    await expect(
47      checkPackagesAsync('/', {
48        packages: ['react-native'],
49        options: { fix: false },
50        // @ts-expect-error
51        packageManager: {},
52        packageManagerArguments: [],
53      })
54    ).rejects.toThrowError(/EXIT/);
55
56    expect(logIncorrectDependencies).toBeCalledTimes(1);
57
58    expect(Log.exit).toBeCalledWith(
59      // Because of ansi
60      expect.stringContaining('Found outdated dependencies'),
61      1
62    );
63  });
64
65  it(`checks packages and exits with zero if all are valid`, async () => {
66    asMock(confirmAsync).mockResolvedValueOnce(false);
67    asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([]);
68    await expect(
69      checkPackagesAsync('/', {
70        packages: ['react-native'],
71        options: { fix: false },
72        // @ts-expect-error
73        packageManager: {},
74        packageManagerArguments: [],
75      })
76    ).rejects.toThrowError(/EXIT/);
77
78    expect(logIncorrectDependencies).toBeCalledTimes(0);
79
80    expect(Log.exit).toBeCalledWith(
81      // Because of ansi
82      expect.stringContaining('Dependencies are up to date'),
83      0
84    );
85  });
86
87  it(`fixes invalid packages`, async () => {
88    asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([
89      {
90        packageName: 'react-native',
91        expectedVersionOrRange: '^1.0.0',
92        actualVersion: '0.69.0',
93      },
94      {
95        packageName: 'expo',
96        expectedVersionOrRange: '^1.0.0',
97        actualVersion: '0.69.0',
98      },
99    ]);
100
101    await checkPackagesAsync('/', {
102      packages: ['react-native', 'expo'],
103      options: { fix: true },
104      // @ts-expect-error
105      packageManager: {},
106      packageManagerArguments: [],
107    });
108
109    expect(installPackagesAsync).toBeCalledWith('/', {
110      packageManager: {},
111      packageManagerArguments: [],
112      packages: ['react-native', 'expo'],
113      sdkVersion: '45.0.0',
114    });
115    expect(logIncorrectDependencies).toBeCalledTimes(1);
116  });
117});
118