1// import { makeRedirectUri } from '../AuthSession';
2
3import { ExecutionEnvironment } from 'expo-constants';
4
5function mockConstants(constants: { [key: string]: any } = {}): void {
6  jest.doMock('expo-constants', () => {
7    const ConstantsModule = jest.requireActual('expo-constants');
8    const { default: Constants } = ConstantsModule;
9    return {
10      ...ConstantsModule,
11      // must explicitly include this in order to mock both default and named exports
12      __esModule: true,
13      default: {
14        ...Constants,
15        ...constants,
16        manifest: { ...Constants.manifest, ...(constants.manifest || {}) },
17      },
18    };
19  });
20}
21
22function mockBareExecutionEnvironment(constants: { [key: string]: any } = {}): void {
23  jest.doMock('expo-constants', () => {
24    const ConstantsModule = jest.requireActual('expo-constants');
25    const { default: Constants } = ConstantsModule;
26    return {
27      ...ConstantsModule,
28      // must explicitly include this in order to mock both default and named exports
29      __esModule: true,
30      default: {
31        executionEnvironment: ExecutionEnvironment.Bare,
32        manifest: { ...Constants.manifest, ...(constants.manifest || {}) },
33      },
34    };
35  });
36}
37
38describe('bare', () => {
39  afterEach(() => {
40    jest.resetModules();
41  });
42  const originalWarn = console.warn;
43
44  beforeEach(() => {
45    console.warn = jest.fn();
46    mockBareExecutionEnvironment();
47  });
48  afterEach(() => (console.warn = originalWarn));
49
50  it(`throws if no scheme is provided or defined`, () => {
51    const { makeRedirectUri } = require('../AuthSession');
52    expect(() => makeRedirectUri()).toThrowError(/Linking requires a build-time /);
53  });
54  it(`uses native value`, () => {
55    const { makeRedirectUri } = require('../AuthSession');
56    // Test that the path is omitted
57    expect(makeRedirectUri({ path: 'bacon', native: 'value:/somn' })).toBe('value:/somn');
58  });
59});
60describe('Managed', () => {
61  describe('Standalone', () => {
62    afterEach(() => {
63      jest.resetModules();
64    });
65
66    it(`creates a redirect URL`, () => {
67      mockConstants({
68        linkingUri: 'exp://exp.host/@test/test',
69        manifest: {
70          scheme: 'demo',
71          hostUri: 'exp.host/@test/test',
72        },
73        appOwnership: 'standalone',
74        executionEnvironment: ExecutionEnvironment.Standalone,
75      });
76      const { makeRedirectUri } = require('../AuthSession');
77      expect(makeRedirectUri()).toBe('demo://');
78    });
79    it(`creates a redirect URL with a custom path`, () => {
80      mockConstants({
81        linkingUri: 'exp://exp.host/@test/test',
82        manifest: {
83          scheme: 'demo',
84        },
85        appOwnership: 'standalone',
86        executionEnvironment: ExecutionEnvironment.Standalone,
87      });
88      const { makeRedirectUri } = require('../AuthSession');
89      expect(makeRedirectUri({ path: 'bacon' })).toBe('demo://bacon');
90    });
91
92    it(`uses native instead of generating a value`, () => {
93      mockConstants({
94        linkingUri: 'exp://exp.host/@test/test',
95        manifest: {
96          scheme: 'demo',
97        },
98        appOwnership: 'standalone',
99        executionEnvironment: ExecutionEnvironment.Standalone,
100      });
101      const { makeRedirectUri } = require('../AuthSession');
102      expect(
103        makeRedirectUri({
104          native: 'native.thing://somn',
105        })
106      ).toBe('native.thing://somn');
107    });
108  });
109
110  describe('Production', () => {
111    afterEach(() => {
112      jest.resetModules();
113    });
114
115    it(`creates a redirect URL`, () => {
116      mockConstants({
117        linkingUri: 'exp://exp.host/@test/test',
118        manifest: {
119          scheme: 'demo',
120          hostUri: 'exp.host/@test/test',
121        },
122        appOwnership: 'expo',
123        executionEnvironment: ExecutionEnvironment.StoreClient,
124      });
125      const { makeRedirectUri } = require('../AuthSession');
126
127      expect(makeRedirectUri()).toBe('exp://exp.host/@test/test');
128    });
129    it(`creates a redirect URL with a custom path`, () => {
130      mockConstants({
131        linkingUri: 'exp://exp.host/@test/test',
132        manifest: {
133          scheme: 'demo',
134          hostUri: 'exp.host/@test/test',
135        },
136        appOwnership: 'expo',
137        executionEnvironment: ExecutionEnvironment.StoreClient,
138      });
139
140      const { makeRedirectUri } = require('../AuthSession');
141
142      expect(makeRedirectUri({ path: 'bacon' })).toBe('exp://exp.host/@test/test/--/bacon');
143    });
144  });
145
146  describe('Development', () => {
147    const devConstants = {
148      linkingUri: 'exp://192.168.1.4:19000/',
149      experienceUrl: 'exp://192.168.1.4:19000',
150      appOwnership: 'expo',
151      executionEnvironment: ExecutionEnvironment.StoreClient,
152      manifest: {
153        scheme: 'demo',
154        hostUri: '192.168.1.4:19000',
155        developer: {
156          projectRoot: '/Users/person/myapp',
157          tool: 'expo-cli',
158        },
159      },
160    };
161    afterEach(() => {
162      jest.resetModules();
163    });
164
165    it(`creates a redirect URL`, () => {
166      mockConstants(devConstants);
167      const { makeRedirectUri } = require('../AuthSession');
168      expect(makeRedirectUri()).toBe('exp://192.168.1.4:19000');
169    });
170    it(`prefers localhost`, () => {
171      mockConstants(devConstants);
172      const { makeRedirectUri } = require('../AuthSession');
173      expect(makeRedirectUri({ preferLocalhost: true })).toBe('exp://localhost:19000');
174    });
175    it(`creates a redirect URL with a custom path`, () => {
176      mockConstants(devConstants);
177      const { makeRedirectUri } = require('../AuthSession');
178      expect(makeRedirectUri({ path: 'bacon' })).toBe('exp://192.168.1.4:19000/--/bacon');
179    });
180  });
181
182  describe('Proxy', () => {
183    afterEach(() => {
184      jest.resetModules();
185    });
186
187    it(`creates a redirect URL with useProxy`, () => {
188      const { makeRedirectUri } = require('../AuthSession');
189
190      // Should create a proxy URL and omit the extra path component
191      expect(makeRedirectUri({ path: 'bacon', useProxy: true })).toBe(
192        'https://auth.expo.io/@test/originaltest'
193      );
194    });
195  });
196});
197