1import { vol } from 'memfs';
2
3import rnFixture from '../../plugins/__tests__/fixtures/react-native-project';
4import { readAndroidManifestAsync } from '../Manifest';
5import {
6  getApplicationIdAsync,
7  getPackage,
8  renameJniOnDiskForType,
9  renamePackageOnDiskForType,
10  setPackageInAndroidManifest,
11  setPackageInBuildGradle,
12} from '../Package';
13import { getAndroidManifestAsync } from '../Paths';
14
15jest.mock('fs');
16
17const EXAMPLE_BUILD_GRADLE = `
18  android {
19      compileSdkVersion rootProject.ext.compileSdkVersion
20      buildToolsVersion rootProject.ext.buildToolsVersion
21
22      defaultConfig {
23          applicationId "com.helloworld"
24          minSdkVersion rootProject.ext.minSdkVersion
25          targetSdkVersion rootProject.ext.targetSdkVersion
26          versionCode 1
27          versionName "1.0"
28      }
29  }
30  `;
31
32describe('package', () => {
33  afterAll(async () => {
34    vol.reset();
35  });
36  it(`returns null if no package is provided`, () => {
37    expect(getPackage({})).toBe(null);
38  });
39
40  it(`returns the package if provided`, () => {
41    expect(getPackage({ android: { package: 'com.example.xyz' } })).toBe('com.example.xyz');
42  });
43
44  it(`returns the applicationId defined in build.gradle`, () => {
45    const projectRoot = '/';
46    vol.fromJSON(rnFixture, projectRoot);
47
48    expect(getApplicationIdAsync(projectRoot)).resolves.toBe('com.bacon.mydevicefamilyproject');
49  });
50
51  it(`sets the applicationId in build.gradle if package is given`, () => {
52    expect(
53      setPackageInBuildGradle({ android: { package: 'my.new.app' } }, EXAMPLE_BUILD_GRADLE)
54    ).toMatch("applicationId 'my.new.app'");
55  });
56
57  it('adds package to android manifest', async () => {
58    const projectRoot = '/';
59    vol.fromJSON(rnFixture, projectRoot);
60
61    let androidManifestJson = await readAndroidManifestAsync(
62      await getAndroidManifestAsync(projectRoot)
63    );
64    androidManifestJson = await setPackageInAndroidManifest(
65      { android: { package: 'com.test.package' } },
66      androidManifestJson
67    );
68
69    expect(androidManifestJson.manifest.$.package).toMatch('com.test.package');
70  });
71});
72
73describe(renamePackageOnDiskForType, () => {
74  afterAll(async () => {
75    vol.reset();
76  });
77  it(`refactors a main project`, async () => {
78    const projectRoot = '/';
79    vol.fromJSON(rnFixture, projectRoot);
80
81    // Ensure the path that will be deleted exists before we
82    // delete it, this helps prevent the test from accidentally breaking.
83    const originalPath = '/android/app/src/main/java/com/reactnativeproject/MainActivity.java';
84
85    expect(vol.toJSON()[originalPath]).toBeDefined();
86    await renamePackageOnDiskForType({
87      projectRoot,
88      type: 'main',
89      packageName: 'com.bacon.foobar',
90    });
91
92    const results = vol.toJSON();
93    // Ensure the file exists in the new location with the new package name
94    expect(results['/android/app/src/main/java/com/bacon/foobar/MainActivity.java']).toMatch(
95      /^package com.bacon.foobar;/
96    );
97    expect(results[originalPath]).toBeUndefined();
98    // Ensure the BUCK file is rewritten
99    expect(results['/android/app/BUCK']).toMatch(/package = "com.bacon.foobar"/);
100  });
101  it(`refactors a debug project`, async () => {
102    const projectRoot = '/';
103    vol.fromJSON(rnFixture, projectRoot);
104    await renamePackageOnDiskForType({
105      projectRoot,
106      type: 'debug',
107      packageName: 'com.bacon.foobar',
108    });
109
110    const results = vol.toJSON();
111    expect(results['/android/app/src/debug/java/com/bacon/foobar/ReactNativeFlipper.java']).toMatch(
112      /package com.bacon.foobar;/
113    );
114  });
115});
116
117describe(renameJniOnDiskForType, () => {
118  afterAll(async () => {
119    vol.reset();
120  });
121  it(`refactors a main project`, async () => {
122    const projectRoot = '/';
123    vol.fromJSON(rnFixture, projectRoot);
124
125    await renameJniOnDiskForType({
126      projectRoot,
127      type: 'main',
128      packageName: 'com.bacon.foobar',
129    });
130
131    const results = vol.toJSON();
132    expect(
133      results['/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h']
134    ).toMatch(
135      /"Lcom\/bacon\/foobar\/newarchitecture\/modules\/MainApplicationTurboModuleManagerDelegate;";/
136    );
137  });
138});
139