1082815dcSEvan Baconimport fs from 'fs';
2082815dcSEvan Baconimport { vol } from 'memfs';
3082815dcSEvan Baconimport path from 'path';
4082815dcSEvan Bacon
5082815dcSEvan Baconimport * as Updates from '../Updates';
6082815dcSEvan Baconimport { getPbxproj } from '../utils/Xcodeproj';
7082815dcSEvan Bacon
8082815dcSEvan Baconconst fsReal = jest.requireActual('fs') as typeof fs;
9082815dcSEvan Baconjest.mock('fs');
10082815dcSEvan Baconjest.mock('resolve-from');
11082815dcSEvan Bacon
12082815dcSEvan Baconconst { silent } = require('resolve-from');
13082815dcSEvan Bacon
14082815dcSEvan Baconconst fixturesPath = path.resolve(__dirname, 'fixtures');
15082815dcSEvan Baconconst sampleCodeSigningCertificatePath = path.resolve(fixturesPath, 'codeSigningCertificate.pem');
16082815dcSEvan Bacon
17082815dcSEvan Bacondescribe('iOS Updates config', () => {
18082815dcSEvan Bacon  beforeEach(() => {
19082815dcSEvan Bacon    const resolveFrom = require('resolve-from');
20082815dcSEvan Bacon    resolveFrom.silent = silent;
21082815dcSEvan Bacon    vol.reset();
22082815dcSEvan Bacon  });
23082815dcSEvan Bacon
24*f0d67e12SMateus Craveiro  it('sets the correct values in Expo.plist', async () => {
25082815dcSEvan Bacon    vol.fromJSON({
26082815dcSEvan Bacon      '/app/hello': fsReal.readFileSync(sampleCodeSigningCertificatePath, 'utf-8'),
27082815dcSEvan Bacon    });
28082815dcSEvan Bacon
29*f0d67e12SMateus Craveiro    const config = await Updates.setUpdatesConfigAsync(
30082815dcSEvan Bacon      '/app',
31082815dcSEvan Bacon      {
32082815dcSEvan Bacon        sdkVersion: '37.0.0',
33082815dcSEvan Bacon        slug: 'my-app',
34082815dcSEvan Bacon        owner: 'owner',
35082815dcSEvan Bacon        updates: {
36082815dcSEvan Bacon          enabled: false,
37082815dcSEvan Bacon          fallbackToCacheTimeout: 2000,
38082815dcSEvan Bacon          checkAutomatically: 'ON_ERROR_RECOVERY',
39082815dcSEvan Bacon          codeSigningCertificate: 'hello',
40082815dcSEvan Bacon          codeSigningMetadata: {
41082815dcSEvan Bacon            alg: 'rsa-v1_5-sha256',
42082815dcSEvan Bacon            keyid: 'test',
43082815dcSEvan Bacon          },
4409bd1012SUmberto Ghio          requestHeaders: {
4509bd1012SUmberto Ghio            'expo-channel-name': 'test',
46fc285a6fSBartosz Kaszubowski            testheader: 'test',
4709bd1012SUmberto Ghio          },
48082815dcSEvan Bacon        },
49082815dcSEvan Bacon      },
50082815dcSEvan Bacon      {} as any,
51082815dcSEvan Bacon      '0.11.0'
52*f0d67e12SMateus Craveiro    );
53*f0d67e12SMateus Craveiro
54*f0d67e12SMateus Craveiro    expect(config).toMatchObject({
55082815dcSEvan Bacon      EXUpdatesEnabled: false,
56082815dcSEvan Bacon      EXUpdatesCheckOnLaunch: 'ERROR_RECOVERY_ONLY',
57082815dcSEvan Bacon      EXUpdatesLaunchWaitMs: 2000,
58082815dcSEvan Bacon      EXUpdatesSDKVersion: '37.0.0',
59082815dcSEvan Bacon      EXUpdatesCodeSigningCertificate: fsReal.readFileSync(
60082815dcSEvan Bacon        sampleCodeSigningCertificatePath,
61082815dcSEvan Bacon        'utf-8'
62082815dcSEvan Bacon      ),
63082815dcSEvan Bacon      EXUpdatesCodeSigningMetadata: { alg: 'rsa-v1_5-sha256', keyid: 'test' },
64fc285a6fSBartosz Kaszubowski      EXUpdatesRequestHeaders: { 'expo-channel-name': 'test', testheader: 'test' },
65082815dcSEvan Bacon    });
66082815dcSEvan Bacon  });
67082815dcSEvan Bacon
68082815dcSEvan Bacon  describe(Updates.ensureBundleReactNativePhaseContainsConfigurationScript, () => {
69082815dcSEvan Bacon    beforeEach(() => {
70082815dcSEvan Bacon      vol.reset();
71082815dcSEvan Bacon      const resolveFrom = require('resolve-from');
72082815dcSEvan Bacon      resolveFrom.silent = silent;
73082815dcSEvan Bacon    });
74082815dcSEvan Bacon
75082815dcSEvan Bacon    it("adds create-manifest-ios.sh line to the 'Bundle React Native code and images' build phase ", () => {
76082815dcSEvan Bacon      vol.fromJSON(
77082815dcSEvan Bacon        {
78082815dcSEvan Bacon          'ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync(
79082815dcSEvan Bacon            path.join(__dirname, 'fixtures/project-without-create-manifest-ios.pbxproj'),
80082815dcSEvan Bacon            'utf-8'
81082815dcSEvan Bacon          ),
82082815dcSEvan Bacon          'node_modules/expo-updates/scripts/create-manifest-ios.sh': 'whatever',
83082815dcSEvan Bacon        },
84082815dcSEvan Bacon        '/app'
85082815dcSEvan Bacon      );
86082815dcSEvan Bacon
87082815dcSEvan Bacon      const xcodeProject = getPbxproj('/app');
88082815dcSEvan Bacon      Updates.ensureBundleReactNativePhaseContainsConfigurationScript('/app', xcodeProject);
89082815dcSEvan Bacon      const bundleReactNative = Updates.getBundleReactNativePhase(xcodeProject);
90082815dcSEvan Bacon      expect(bundleReactNative.shellScript).toMatchSnapshot();
91082815dcSEvan Bacon    });
92082815dcSEvan Bacon
93082815dcSEvan Bacon    it('fixes the path to create-manifest-ios.sh in case of a monorepo', () => {
94082815dcSEvan Bacon      // Pseudo node module resolution since actually mocking it could prove challenging.
95082815dcSEvan Bacon      // In a yarn workspace, resolve-from would be able to locate a module in any node_module folder if properly linked.
96082815dcSEvan Bacon      const resolveFrom = require('resolve-from');
97082815dcSEvan Bacon      resolveFrom.silent = (p, a) => {
98082815dcSEvan Bacon        return silent(path.join(p, '..'), a);
99082815dcSEvan Bacon      };
100082815dcSEvan Bacon
101082815dcSEvan Bacon      vol.fromJSON(
102082815dcSEvan Bacon        {
103082815dcSEvan Bacon          'workspace/ios/testproject.xcodeproj/project.pbxproj': fsReal.readFileSync(
104082815dcSEvan Bacon            path.join(
105082815dcSEvan Bacon              __dirname,
106082815dcSEvan Bacon              'fixtures/project-with-incorrect-create-manifest-ios-path.pbxproj'
107082815dcSEvan Bacon            ),
108082815dcSEvan Bacon            'utf-8'
109082815dcSEvan Bacon          ),
110082815dcSEvan Bacon          'node_modules/expo-updates/scripts/create-manifest-ios.sh': 'whatever',
111082815dcSEvan Bacon        },
112082815dcSEvan Bacon        '/app'
113082815dcSEvan Bacon      );
114082815dcSEvan Bacon      const xcodeProject = getPbxproj('/app/workspace');
115082815dcSEvan Bacon      Updates.ensureBundleReactNativePhaseContainsConfigurationScript(
116082815dcSEvan Bacon        '/app/workspace',
117082815dcSEvan Bacon        xcodeProject
118082815dcSEvan Bacon      );
119082815dcSEvan Bacon      const bundleReactNative = Updates.getBundleReactNativePhase(xcodeProject);
120082815dcSEvan Bacon      expect(bundleReactNative.shellScript).toMatchSnapshot();
121082815dcSEvan Bacon    });
122082815dcSEvan Bacon  });
123082815dcSEvan Bacon});
124