@sentry/wizard
Version:
Sentry wizard helping you to configure your project
128 lines (103 loc) • 3.81 kB
text/typescript
jest.mock('../../../Helper/Logging.ts'); // We mock logging to not pollute the output
jest.mock('child_process');
import * as child_process from 'child_process';
import * as fs from 'fs';
import type { Answers } from 'inquirer';
import * as path from 'path';
import * as process from 'process';
import * as rimraf from 'rimraf';
import type { Args} from '../../../Constants';
import { Integration, Platform } from '../../../Constants';
import { ReactNative } from '../ReactNative';
const testDir = 'rn-test';
const iosIndexJs = 'index.ios.js';
const appTsx = 'src/App.tsx';
const appBuildGradle = 'android/app/build.gradle';
const yarnLock = 'yarn.lock';
const dummyJsContent = 'import React from "react";\n';
const dummyAppBuildGradleContent = 'apply plugin: "com.facebook.react"\n\nandroid {\n}\n';
const testArgs = {
debug: false,
integration: Integration.reactNative,
platform: [Platform.ios],
quiet: true,
skipConnect: true,
uninstall: false,
url: 'https://not.used',
};
const mockIosAnswers: Answers = {
shouldConfigurePlatforms: { 'ios': true },
config: {
dsn: {
public: 'dns.public.com',
},
},
};
const mockAndroidAnswers: Answers = {
shouldConfigurePlatforms: { 'android': true },
config: {
dsn: {
public: 'dns.public.com',
},
},
};
const originalExec = child_process.exec;
const restoreExec = (): void => {
(child_process as any).exec = originalExec;
}
const mockExec = (): void => {
(child_process.exec as unknown as jest.Mock)
.mockImplementation((_command, callback) => callback(null, { stdout: '' }));
}
describe('ReactNative', () => {
const defaultCwd = process.cwd();
beforeEach(() => {
rimraf.sync(testDir);
fs.mkdirSync(testDir);
process.chdir(testDir);
fs.writeFileSync(iosIndexJs, dummyJsContent);
fs.mkdirSync(path.dirname(appTsx), { recursive: true });
fs.writeFileSync(appTsx, dummyJsContent);
fs.mkdirSync(path.dirname(appBuildGradle), { recursive: true });
fs.writeFileSync(appBuildGradle, dummyAppBuildGradleContent);
fs.writeFileSync(yarnLock, '');
mockExec();
});
afterEach(() => {
restoreExec();
process.chdir(defaultCwd);
rimraf.sync(testDir);
});
test('patches js files', async () => {
const project = new ReactNative(testArgs as Args);
await project.emit(mockIosAnswers);
const patchedIosIndexJs = fs.readFileSync(iosIndexJs, 'utf8');
const patchedAppTsx = fs.readFileSync(appTsx, 'utf8');
const expectedPatch = 'import React from "react";\n\n' +
'import * as Sentry from \'@sentry/react-native\';\n\n' +
'Sentry.init({ \n' +
' dsn: \'dns.public.com\', \n' +
'});\n\n';
expect(patchedIosIndexJs).toEqual(expectedPatch);
expect(patchedAppTsx).toEqual(expectedPatch);
});
test('patches android app build gradle file', async () => {
const project = new ReactNative(testArgs as Args);
await project.emit(mockAndroidAnswers);
const patchedAppBuildGradle = fs.readFileSync(appBuildGradle, 'utf8');
const expectedPatch = 'apply plugin: "com.facebook.react"\n\n' +
'apply from: "../../node_modules/@sentry/react-native/sentry.gradle"\n' +
'android {\n}\n';
expect(patchedAppBuildGradle).toEqual(expectedPatch);
});
test('does install sentry sdk', async () => {
const project = new ReactNative(testArgs as Args);
await project.emit(mockIosAnswers);
expect(child_process.exec).toHaveBeenCalledWith('yarn add @sentry/react-native', expect.anything());
});
test('executes pod install', async () => {
const project = new ReactNative(testArgs as Args);
await project.emit(mockIosAnswers);
expect(child_process.exec).toHaveBeenCalledWith('npx --yes pod-install --non-interactive --quiet', expect.anything());
});
});