1import { vol } from 'memfs';
2import { resolve } from 'path';
3
4import { copyFilePathToPathAsync } from '../../utils/fs';
5import {
6  applyPlugin,
7  getGoogleServicesFilePath,
8  setClassPath,
9  setGoogleServicesFile,
10} from '../GoogleServices';
11
12jest.mock('fs');
13jest.mock('fs/promises');
14
15jest.mock('../../utils/fs', () => ({
16  copyFilePathToPathAsync: jest.fn(),
17}));
18
19describe(getGoogleServicesFilePath, () => {
20  it(`returns null if no googleServicesFile is provided`, () => {
21    expect(getGoogleServicesFilePath({})).toBe(null);
22  });
23
24  it(`returns googleServicesFile path if provided`, () => {
25    expect(
26      getGoogleServicesFilePath({
27        android: {
28          googleServicesFile: 'path/to/google-services.json',
29        },
30      })
31    ).toBe('path/to/google-services.json');
32  });
33});
34
35describe(setGoogleServicesFile, () => {
36  afterAll(() => {
37    vol.reset();
38  });
39
40  const projectRoot = '/';
41  beforeEach(() => {
42    vol.fromJSON(
43      {
44        'google-services.json': '{}',
45      },
46      projectRoot
47    );
48  });
49
50  it(`copies google services file to android/app`, async () => {
51    expect(
52      await setGoogleServicesFile(
53        {
54          android: {
55            googleServicesFile: './google-services.json',
56          },
57        },
58        projectRoot
59      )
60    ).toBe(true);
61
62    expect(copyFilePathToPathAsync).toHaveBeenLastCalledWith(
63      '/google-services.json',
64      '/android/app/google-services.json'
65    );
66  });
67
68  it(`copies google services file to custom target path`, async () => {
69    const customTargetPath = './not/sure/why/youd/do/this/google-services.json';
70    expect(
71      await setGoogleServicesFile(
72        {
73          android: {
74            googleServicesFile: './google-services.json',
75          },
76        },
77        projectRoot,
78        customTargetPath
79      )
80    ).toBe(true);
81
82    expect(copyFilePathToPathAsync).toHaveBeenCalledWith(
83      resolve(projectRoot, 'google-services.json'),
84      resolve(projectRoot, customTargetPath)
85    );
86  });
87});
88
89describe(setClassPath, () => {
90  const validConfig = { android: { googleServicesFile: 'g.json' } };
91  const EXAMPLE_BUILD_GRADLE = `
92buildscript {
93    ext {
94        buildToolsVersion = "28.0.3"
95    }
96    repositories {
97        google()
98        jcenter()
99    }
100    dependencies {
101        classpath 'com.android.tools.build:gradle:3.5.3'
102
103    }
104}
105`;
106
107  const EXPECTED_BUILD_GRADLE = `
108buildscript {
109    ext {
110        buildToolsVersion = "28.0.3"
111    }
112    repositories {
113        google()
114        jcenter()
115    }
116    dependencies {
117        classpath 'com.google.gms:google-services:4.3.3'
118        classpath 'com.android.tools.build:gradle:3.5.3'
119
120    }
121}
122`;
123  it(`sets classpath in build.gradle if needed`, () => {
124    expect(setClassPath(validConfig, EXAMPLE_BUILD_GRADLE)).toEqual(EXPECTED_BUILD_GRADLE);
125  });
126
127  it(`does not set classpath in build.gradle multiple times`, () => {
128    expect(setClassPath(validConfig, EXPECTED_BUILD_GRADLE)).toEqual(EXPECTED_BUILD_GRADLE);
129  });
130});
131
132describe(applyPlugin, () => {
133  const validConfig = { android: { googleServicesFile: 'g.json' } };
134  const EXAMPLE_APP_BUILD_GRADLE = `
135// Blah blah blah
136task copyDownloadableDepsToLibs(type: Copy) {
137    from configurations.compile
138    into 'libs'
139}
140
141apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
142applyNativeModulesAppBuildGradle(project)`;
143
144  const EXPECTED_APP_BUILD_GRADLE = `
145// Blah blah blah
146task copyDownloadableDepsToLibs(type: Copy) {
147    from configurations.compile
148    into 'libs'
149}
150
151apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
152applyNativeModulesAppBuildGradle(project)
153apply plugin: 'com.google.gms.google-services'`;
154
155  it(`applies the plugin in app/build.gradle if needed`, () => {
156    expect(applyPlugin(validConfig, EXAMPLE_APP_BUILD_GRADLE)).toEqual(EXPECTED_APP_BUILD_GRADLE);
157  });
158
159  it(`does not apply the plugin multiple times`, () => {
160    expect(applyPlugin(validConfig, EXPECTED_APP_BUILD_GRADLE)).toEqual(EXPECTED_APP_BUILD_GRADLE);
161  });
162});
163