1d42dd5d4SCedric van Puttenimport { ExpoConfig } from '@expo/config';
2d42dd5d4SCedric van Puttenimport { Middleware } from 'metro-config';
3d42dd5d4SCedric van Putten
4d42dd5d4SCedric van Puttenimport { createDebuggerTelemetryMiddleware, findDebugTool } from '../metroDebuggerMiddleware';
5d42dd5d4SCedric van Puttenimport { logEventAsync } from '../rudderstackClient';
6d42dd5d4SCedric van Putten
7d42dd5d4SCedric van Puttenjest.mock('../getMetroDebugProperties');
8d42dd5d4SCedric van Puttenjest.mock('../rudderstackClient');
9d42dd5d4SCedric van Putten
10d42dd5d4SCedric van Puttenconst FLIPPER_UA = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Flipper/0.177.0 Chrome/100.0.4896.143 Electron/18.2.0 Safari/537.36`;
11d42dd5d4SCedric van Puttenconst CHROME_ORIGIN = `https://chrome-devtools-frontend.appspot.com`;
12d42dd5d4SCedric van Putten
13d42dd5d4SCedric van Puttenconst fakeExpoConfig = {
14d42dd5d4SCedric van Putten  sdkVersion: '47.0.0',
15d42dd5d4SCedric van Putten  jsEngine: 'hermes',
16d42dd5d4SCedric van Putten} as ExpoConfig;
17d42dd5d4SCedric van Putten
18d42dd5d4SCedric van Putten/** Create a fake request object, based on the provided options */
19d42dd5d4SCedric van Puttenconst req = (options: { url: string; userAgent?: string; origin?: string }) =>
20d42dd5d4SCedric van Putten  ({
21d42dd5d4SCedric van Putten    url: options.url,
22d42dd5d4SCedric van Putten    headers: {
23d42dd5d4SCedric van Putten      'user-agent': options.userAgent,
24d42dd5d4SCedric van Putten      origin: options.origin,
25d42dd5d4SCedric van Putten    },
26*8a424bebSJames Ide  }) as Parameters<Middleware>[0];
27d42dd5d4SCedric van Putten
28d42dd5d4SCedric van Puttendescribe(findDebugTool, () => {
29d42dd5d4SCedric van Putten  it('returns flipper from user agent', () => {
30d42dd5d4SCedric van Putten    expect(findDebugTool(req({ url: '/json', userAgent: FLIPPER_UA }))).toMatchObject({
31d42dd5d4SCedric van Putten      name: 'flipper',
32d42dd5d4SCedric van Putten      version: '0.177.0',
33d42dd5d4SCedric van Putten    });
34d42dd5d4SCedric van Putten  });
35d42dd5d4SCedric van Putten
36d42dd5d4SCedric van Putten  it('returns chrome from origin', () => {
37d42dd5d4SCedric van Putten    expect(findDebugTool(req({ url: '/index.map', origin: CHROME_ORIGIN }))).toMatchObject({
38d42dd5d4SCedric van Putten      name: 'chrome',
39d42dd5d4SCedric van Putten    });
40d42dd5d4SCedric van Putten  });
41d42dd5d4SCedric van Putten});
42d42dd5d4SCedric van Putten
43d42dd5d4SCedric van Puttendescribe(createDebuggerTelemetryMiddleware, () => {
44d42dd5d4SCedric van Putten  it('reports known tool from user agent', () => {
45d42dd5d4SCedric van Putten    const middleware = createDebuggerTelemetryMiddleware('/fake-project', fakeExpoConfig);
46d42dd5d4SCedric van Putten    const next = jest.fn();
47d42dd5d4SCedric van Putten
48d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: FLIPPER_UA }), {} as any, next);
49d42dd5d4SCedric van Putten
50d42dd5d4SCedric van Putten    expect(logEventAsync).toHaveBeenCalled();
51d42dd5d4SCedric van Putten  });
52d42dd5d4SCedric van Putten
53d42dd5d4SCedric van Putten  it('only reports known tool once', () => {
54d42dd5d4SCedric van Putten    const middleware = createDebuggerTelemetryMiddleware('/fake-project', fakeExpoConfig);
55d42dd5d4SCedric van Putten    const next = jest.fn();
56d42dd5d4SCedric van Putten
57d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: FLIPPER_UA }), {} as any, next);
58d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: FLIPPER_UA }), {} as any, next);
59d42dd5d4SCedric van Putten
60d42dd5d4SCedric van Putten    expect(logEventAsync).toHaveBeenCalledTimes(1);
61d42dd5d4SCedric van Putten    expect(next).toHaveBeenCalledTimes(2);
62d42dd5d4SCedric van Putten  });
63d42dd5d4SCedric van Putten
64d42dd5d4SCedric van Putten  it('does not report with unknown user agent', () => {
65d42dd5d4SCedric van Putten    const middleware = createDebuggerTelemetryMiddleware('/fake-project', fakeExpoConfig);
66d42dd5d4SCedric van Putten    const next = jest.fn();
67d42dd5d4SCedric van Putten
68d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: 'unknown/4.2.0' }), {} as any, next);
69d42dd5d4SCedric van Putten
70d42dd5d4SCedric van Putten    expect(logEventAsync).not.toHaveBeenCalled();
71d42dd5d4SCedric van Putten  });
72d42dd5d4SCedric van Putten
73d42dd5d4SCedric van Putten  it('does not report when telemetry is turned off', () => {
74d42dd5d4SCedric van Putten    process.env.EXPO_NO_TELEMETRY = 'true';
75d42dd5d4SCedric van Putten
76d42dd5d4SCedric van Putten    const middleware = createDebuggerTelemetryMiddleware('/fake-project', fakeExpoConfig);
77d42dd5d4SCedric van Putten    const next = jest.fn();
78d42dd5d4SCedric van Putten
79d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: FLIPPER_UA }), {} as any, next);
80d42dd5d4SCedric van Putten
81d42dd5d4SCedric van Putten    expect(logEventAsync).not.toHaveBeenCalled();
82d42dd5d4SCedric van Putten
83d42dd5d4SCedric van Putten    delete process.env.EXPO_NO_TELEMETRY;
84d42dd5d4SCedric van Putten  });
85d42dd5d4SCedric van Putten
86d42dd5d4SCedric van Putten  it('does not report when app is not using hermes', () => {
87d42dd5d4SCedric van Putten    const expoConfig = { ...fakeExpoConfig, jsEngine: 'jsc' as const };
88d42dd5d4SCedric van Putten    const middleware = createDebuggerTelemetryMiddleware('/fake-project', expoConfig);
89d42dd5d4SCedric van Putten    const next = jest.fn();
90d42dd5d4SCedric van Putten
91d42dd5d4SCedric van Putten    middleware(req({ url: '/json', userAgent: FLIPPER_UA }), {} as any, next);
92d42dd5d4SCedric van Putten
93d42dd5d4SCedric van Putten    expect(logEventAsync).not.toHaveBeenCalled();
94d42dd5d4SCedric van Putten  });
95d42dd5d4SCedric van Putten});
96