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 { fixPackagesAsync } from '../installAsync';
10
11jest.mock('../../log');
12
13jest.mock('../../utils/prompts');
14
15jest.mock('../installAsync', () => ({
16  fixPackagesAsync: 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        packageType: 'dependencies',
43        expectedVersionOrRange: '^1.0.0',
44        actualVersion: '0.69.0',
45      },
46    ]);
47    await expect(
48      checkPackagesAsync('/', {
49        packages: ['react-native'],
50        options: { fix: false },
51        // @ts-expect-error
52        packageManager: {},
53        packageManagerArguments: [],
54      })
55    ).rejects.toThrowError(/EXIT/);
56
57    expect(logIncorrectDependencies).toBeCalledTimes(1);
58
59    expect(Log.exit).toBeCalledWith(
60      // Because of ansi
61      expect.stringContaining('Found outdated dependencies'),
62      1
63    );
64  });
65
66  it(`checks packages and exits with zero if all are valid`, async () => {
67    asMock(confirmAsync).mockResolvedValueOnce(false);
68    asMock(getVersionedDependenciesAsync).mockResolvedValueOnce([]);
69    await expect(
70      checkPackagesAsync('/', {
71        packages: ['react-native'],
72        options: { fix: false },
73        // @ts-expect-error
74        packageManager: {},
75        packageManagerArguments: [],
76      })
77    ).rejects.toThrowError(/EXIT/);
78
79    expect(logIncorrectDependencies).toBeCalledTimes(0);
80
81    expect(Log.exit).toBeCalledWith(
82      // Because of ansi
83      expect.stringContaining('Dependencies are up to date'),
84      0
85    );
86  });
87
88  it(`fixes invalid packages`, async () => {
89    const issues: Awaited<ReturnType<typeof getVersionedDependenciesAsync>> = [
90      {
91        packageName: 'react-native',
92        packageType: 'dependencies',
93        expectedVersionOrRange: '^1.0.0',
94        actualVersion: '0.69.0',
95      },
96      {
97        packageName: 'expo',
98        packageType: 'dependencies',
99        expectedVersionOrRange: '^1.0.0',
100        actualVersion: '0.69.0',
101      },
102    ];
103
104    asMock(getVersionedDependenciesAsync).mockResolvedValueOnce(issues);
105
106    await checkPackagesAsync('/', {
107      packages: ['react-native', 'expo'],
108      options: { fix: true },
109      // @ts-expect-error
110      packageManager: {},
111      packageManagerArguments: [],
112    });
113
114    expect(fixPackagesAsync).toBeCalledWith('/', {
115      packageManager: {},
116      packageManagerArguments: [],
117      packages: issues,
118      sdkVersion: '45.0.0',
119    });
120    expect(logIncorrectDependencies).toBeCalledTimes(1);
121  });
122});
123