Skip to content

Commit

Permalink
Added module loading tests
Browse files Browse the repository at this point in the history
drop amplitude

Update rudderstackClient.ts
  • Loading branch information
EvanBacon committed Jan 27, 2022
1 parent 4a52216 commit 5ef009a
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 68 deletions.
3 changes: 1 addition & 2 deletions packages/expo/cli/utils/__tests__/api-test.ts
Expand Up @@ -2,8 +2,7 @@ import assert from 'assert';
import { RequestError } from 'got/dist/source';
import nock from 'nock';

import { apiClient, getExpoApiBaseUrl } from '../api';
import { ApiV2Error } from '../errors';
import { ApiV2Error, apiClient, getExpoApiBaseUrl } from '../api';

it('converts Expo APIv2 error to ApiV2Error', async () => {
nock(getExpoApiBaseUrl())
Expand Down
36 changes: 10 additions & 26 deletions packages/expo/cli/utils/analytics/rudderstackClient.ts
Expand Up @@ -3,6 +3,7 @@ import os from 'os';
import { URL } from 'url';
import { v4 as uuidv4 } from 'uuid';

import { EXPO_LOCAL, EXPO_STAGING, EXPO_NO_TELEMETRY } from '../env';
import UserSettings from '../user/UserSettings';

const PLATFORM_TO_ANALYTICS_PLATFORM: { [platform: string]: string } = {
Expand All @@ -12,34 +13,17 @@ const PLATFORM_TO_ANALYTICS_PLATFORM: { [platform: string]: string } = {
};

let rudderstackClient: RudderAnalytics | null = null;
let userIdentified = false;
let identifier = false;
let identifyData: {
userId: string;
deviceId: string;
traits: Record<string, any>;
} | null = null;

export async function initAsync(): Promise<void> {
// TODO: remove after some time
const amplitudeEnabled = await UserSettings.getAsync('amplitudeEnabled', null);
if (amplitudeEnabled !== null) {
await UserSettings.setAsync('analyticsEnabled', amplitudeEnabled);
await UserSettings.deleteKeyAsync('amplitudeEnabled');
}
const amplitudeDeviceId = await UserSettings.getAsync('amplitudeDeviceId', null);
if (amplitudeDeviceId !== null) {
await UserSettings.setAsync('analyticsDeviceId', amplitudeDeviceId);
await UserSettings.deleteKeyAsync('amplitudeDeviceId');
}
// TODO: cut here
if (process.env.DISABLE_EAS_ANALYTICS) {
await UserSettings.setAsync('analyticsEnabled', false);
}

const analyticsEnabled = await UserSettings.getAsync('analyticsEnabled', true);
if (analyticsEnabled) {
if (EXPO_NO_TELEMETRY) {
const config =
process.env.EXPO_STAGING || process.env.EXPO_LOCAL
EXPO_STAGING || EXPO_LOCAL
? {
// staging environment
rudderstackWriteKey: '1wpX20Da4ltFGSXbPFYUL00Chb7',
Expand Down Expand Up @@ -74,7 +58,7 @@ export async function setUserDataAsync(userId: string, traits: Record<string, an
traits,
};

ensureUserIdentified();
ensureIdentified();
}

export async function flushAsync(): Promise<void> {
Expand All @@ -87,7 +71,7 @@ export function logEvent(name: string, properties: Record<string, any> = {}): vo
if (!rudderstackClient) {
return;
}
ensureUserIdentified();
ensureIdentified();

const { userId, deviceId } = identifyData ?? {};
const commonEventProperties = { source_version: process.env.__EXPO_VERSION, source: 'expo' };
Expand All @@ -101,8 +85,8 @@ export function logEvent(name: string, properties: Record<string, any> = {}): vo
});
}

function ensureUserIdentified(): void {
if (!rudderstackClient || userIdentified || !identifyData) {
function ensureIdentified(): void {
if (!rudderstackClient || identifier || !identifyData) {
return;
}

Expand All @@ -111,15 +95,15 @@ function ensureUserIdentified(): void {
anonymousId: identifyData.deviceId,
traits: identifyData.traits,
});
userIdentified = true;
identifier = true;
}

function getRudderStackContext(): Record<string, any> {
const platform = PLATFORM_TO_ANALYTICS_PLATFORM[os.platform()] || os.platform();
return {
os: { name: platform, version: os.release() },
device: { type: platform, model: platform },
app: { name: 'expo', version: process.env.__EXPO_VERSION ?? undefined },
app: { name: 'expo', version: process.env.__EXPO_VERSION },
};
}

Expand Down
27 changes: 26 additions & 1 deletion packages/expo/cli/utils/api.ts
@@ -1,9 +1,34 @@
import { JSONValue } from '@expo/json-file';
import got, { HTTPError, NormalizedOptions, RequestError } from 'got';

import { EXPO_LOCAL, EXPO_STAGING } from './env';
import { ApiV2Error } from './errors';
import { getAccessToken, getSessionSecret } from './user/sessionStorage';

export class ApiV2Error extends RequestError {
readonly name = 'ApiV2Error';
readonly expoApiV2ErrorCode: string;
readonly expoApiV2ErrorDetails?: JSONValue;
readonly expoApiV2ErrorServerStack?: string;
readonly expoApiV2ErrorMetadata?: object;

constructor(
originalError: HTTPError,
response: {
message: string;
code: string;
stack?: string;
details?: JSONValue;
metadata?: object;
}
) {
super(response.message, originalError, originalError.request);
this.expoApiV2ErrorCode = response.code;
this.expoApiV2ErrorDetails = response.details;
this.expoApiV2ErrorServerStack = response.stack;
this.expoApiV2ErrorMetadata = response.metadata;
}
}

export const apiClient = got.extend({
prefixUrl: getExpoApiBaseUrl() + '/v2/',
hooks: {
Expand Down
3 changes: 3 additions & 0 deletions packages/expo/cli/utils/env.ts
Expand Up @@ -16,3 +16,6 @@ export const EXPO_LOCAL = boolish('EXPO_LOCAL', false);

/** Is running in non-interactive CI mode */
export const CI = boolish('CI', false);

/** Disable telemetry (analytics) */
export const EXPO_NO_TELEMETRY = boolish('EXPO_NO_TELEMETRY', false);
35 changes: 5 additions & 30 deletions packages/expo/cli/utils/errors.ts
@@ -1,35 +1,7 @@
import { JSONValue } from '@expo/json-file';
import { AssertionError } from 'assert';
import chalk from 'chalk';
import { HTTPError, RequestError } from 'got/dist/source';

import { exit } from '../log';
import { EXPO_DEBUG } from './env';

export class ApiV2Error extends RequestError {
readonly name = 'ApiV2Error';
readonly expoApiV2ErrorCode: string;
readonly expoApiV2ErrorDetails?: JSONValue;
readonly expoApiV2ErrorServerStack?: string;
readonly expoApiV2ErrorMetadata?: object;

constructor(
originalError: HTTPError,
response: {
message: string;
code: string;
stack?: string;
details?: JSONValue;
metadata?: object;
}
) {
super(response.message, originalError, originalError.request);
this.expoApiV2ErrorCode = response.code;
this.expoApiV2ErrorDetails = response.details;
this.expoApiV2ErrorServerStack = response.stack;
this.expoApiV2ErrorMetadata = response.metadata;
}
}

const ERROR_PREFIX = 'Error: ';

Expand Down Expand Up @@ -82,10 +54,13 @@ export function logCmdError(error: Error): never {
} else if (
error instanceof CommandError ||
error instanceof AssertionError ||
error instanceof ApiV2Error
error.name === 'ApiV2Error'
) {
// Print the stack trace in debug mode only.
exit(chalk.red(error.toString()) + (EXPO_DEBUG ? '\n' + chalk.gray(error.stack) : ''));
exit(
chalk.red(error.toString()) +
(require('./env').EXPO_DEBUG ? '\n' + chalk.gray(error.stack) : '')
);
}

exit(chalk.red(error.toString()) + '\n' + chalk.gray(error.stack));
Expand Down
2 changes: 0 additions & 2 deletions packages/expo/cli/utils/user/UserSettings.ts
Expand Up @@ -27,8 +27,6 @@ const SETTINGS_FILE_PATH = path.join(getConfigDirectory(), 'user-settings.json')

export type UserSettingsData = {
appleId?: string;
amplitudeDeviceId?: string;
amplitudeEnabled?: boolean;
analyticsDeviceId?: string;
analyticsEnabled?: boolean;
};
Expand Down
9 changes: 7 additions & 2 deletions packages/expo/cli/utils/user/__tests__/actions-test.ts
@@ -1,11 +1,16 @@
import { ApiV2Error } from '../../errors';
import { ApiV2Error } from '../../api';
import { promptAsync } from '../../prompts';
import { ensureActorHasUsername, showLoginPromptAsync } from '../actions';
import { retryUsernamePasswordAuthWithOTPAsync, UserSecondFactorDeviceMethod } from '../otp';
import { Actor, loginAsync } from '../user';

jest.mock('../../prompts');
jest.mock('../../api');
jest.mock('../../api', () => {
const { ApiV2Error } = jest.requireActual('../../api');
return {
ApiV2Error,
};
});
jest.mock('../otp');
jest.mock('../user');

Expand Down
3 changes: 2 additions & 1 deletion packages/expo/cli/utils/user/actions.ts
Expand Up @@ -2,7 +2,8 @@ import assert from 'assert';
import chalk from 'chalk';

import * as Log from '../../log';
import { ApiV2Error, CommandError } from '../errors';
import { ApiV2Error } from '../api';
import { CommandError } from '../errors';
import { learnMore } from '../link';
import promptAsync, { Question } from '../prompts';
import { retryUsernamePasswordAuthWithOTPAsync } from './otp';
Expand Down
18 changes: 17 additions & 1 deletion packages/expo/e2e/__tests__/login-test.ts
@@ -1,7 +1,7 @@
/* eslint-env jest */
import fs from 'fs/promises';

import { execute, projectRoot } from './utils';
import { execute, getLoadedModulesAsync, projectRoot } from './utils';

const originalForceColor = process.env.FORCE_COLOR;
const originalCI = process.env.CI;
Expand All @@ -15,6 +15,22 @@ afterAll(() => {
process.env.CI = originalCI;
});

it('loads expected modules by default', async () => {
const modules = await getLoadedModulesAsync(`require('../../build-cli/cli/login');`);
expect(modules).toStrictEqual([
'node_modules/ansi-styles/index.js',
'node_modules/arg/index.js',
'node_modules/chalk/source/index.js',
'node_modules/chalk/source/util.js',
'node_modules/has-flag/index.js',
'node_modules/supports-color/index.js',
'packages/expo/build-cli/cli/log.js',
'packages/expo/build-cli/cli/login/index.js',
'packages/expo/build-cli/cli/utils/args.js',
'packages/expo/build-cli/cli/utils/errors.js',
]);
});

it('runs `npx expo login --help`', async () => {
const results = await execute('login', '--help');
expect(results.stdout).toMatchInlineSnapshot(`
Expand Down
18 changes: 17 additions & 1 deletion packages/expo/e2e/__tests__/logout-test.ts
@@ -1,7 +1,7 @@
/* eslint-env jest */
import fs from 'fs/promises';

import { execute, projectRoot } from './utils';
import { execute, getLoadedModulesAsync, projectRoot } from './utils';

const originalForceColor = process.env.FORCE_COLOR;

Expand All @@ -13,6 +13,22 @@ afterAll(() => {
process.env.FORCE_COLOR = originalForceColor;
});

it('loads expected modules by default', async () => {
const modules = await getLoadedModulesAsync(`require('../../build-cli/cli/logout');`);
expect(modules).toStrictEqual([
'node_modules/ansi-styles/index.js',
'node_modules/arg/index.js',
'node_modules/chalk/source/index.js',
'node_modules/chalk/source/util.js',
'node_modules/has-flag/index.js',
'node_modules/supports-color/index.js',
'packages/expo/build-cli/cli/log.js',
'packages/expo/build-cli/cli/logout/index.js',
'packages/expo/build-cli/cli/utils/args.js',
'packages/expo/build-cli/cli/utils/errors.js',
]);
});

it('runs `npx expo logout --help`', async () => {
const results = await execute('logout', '--help');
expect(results.stdout).toMatchInlineSnapshot(`
Expand Down
18 changes: 17 additions & 1 deletion packages/expo/e2e/__tests__/register-test.ts
@@ -1,7 +1,7 @@
/* eslint-env jest */
import fs from 'fs/promises';

import { execute, projectRoot } from './utils';
import { execute, getLoadedModulesAsync, projectRoot } from './utils';

const originalForceColor = process.env.FORCE_COLOR;
const originalCI = process.env.CI;
Expand All @@ -15,6 +15,22 @@ afterAll(() => {
process.env.CI = originalCI;
});

it('loads expected modules by default', async () => {
const modules = await getLoadedModulesAsync(`require('../../build-cli/cli/register');`);
expect(modules).toStrictEqual([
'node_modules/ansi-styles/index.js',
'node_modules/arg/index.js',
'node_modules/chalk/source/index.js',
'node_modules/chalk/source/util.js',
'node_modules/has-flag/index.js',
'node_modules/supports-color/index.js',
'packages/expo/build-cli/cli/log.js',
'packages/expo/build-cli/cli/register/index.js',
'packages/expo/build-cli/cli/utils/args.js',
'packages/expo/build-cli/cli/utils/errors.js',
]);
});

it('runs `npx expo register --help`', async () => {
const results = await execute('register', '--help');
expect(results.stdout).toMatchInlineSnapshot(`
Expand Down
18 changes: 17 additions & 1 deletion packages/expo/e2e/__tests__/whoami-test.ts
Expand Up @@ -2,7 +2,7 @@
import fs from 'fs/promises';
import os from 'os';

import { execute, projectRoot } from './utils';
import { execute, getLoadedModulesAsync, projectRoot } from './utils';

const originalForceColor = process.env.FORCE_COLOR;
beforeAll(async () => {
Expand All @@ -13,6 +13,22 @@ afterAll(() => {
process.env.FORCE_COLOR = originalForceColor;
});

it('loads expected modules by default', async () => {
const modules = await getLoadedModulesAsync(`require('../../build-cli/cli/whoami');`);
expect(modules).toStrictEqual([
'node_modules/ansi-styles/index.js',
'node_modules/arg/index.js',
'node_modules/chalk/source/index.js',
'node_modules/chalk/source/util.js',
'node_modules/has-flag/index.js',
'node_modules/supports-color/index.js',
'packages/expo/build-cli/cli/log.js',
'packages/expo/build-cli/cli/utils/args.js',
'packages/expo/build-cli/cli/utils/errors.js',
'packages/expo/build-cli/cli/whoami/index.js',
]);
});

it('runs `npx expo whoami --help`', async () => {
const results = await execute('whoami', '--help');
expect(results.stdout).toMatchInlineSnapshot(`
Expand Down

0 comments on commit 5ef009a

Please sign in to comment.