18d307f52SEvan Baconimport nock from 'nock'; 28d307f52SEvan Bacon 38d307f52SEvan Baconimport { getExpoApiBaseUrl } from '../../../api/endpoint'; 48d307f52SEvan Baconimport * as ProjectDevices from '../../project/devices'; 58d307f52SEvan Baconimport { DevelopmentSession } from '../DevelopmentSession'; 68d307f52SEvan Bacon 78d307f52SEvan Baconconst asMock = (fn: any): jest.Mock => fn as jest.Mock; 88d307f52SEvan Bacon 98d307f52SEvan Baconjest.mock('../../project/devices', () => ({ 108d307f52SEvan Bacon getDevicesInfoAsync: jest.fn(), 118d307f52SEvan Bacon})); 128d307f52SEvan Baconjest.mock('../../../api/user/user'); 138d307f52SEvan Bacon 148d307f52SEvan Bacondescribe(`startAsync`, () => { 15*e32ccf9fSEvan Bacon beforeEach(() => { 16*e32ccf9fSEvan Bacon delete process.env.EXPO_OFFLINE; 17*e32ccf9fSEvan Bacon }); 188d307f52SEvan Bacon it(`starts a dev session`, async () => { 1981e9e3beSEvan Bacon const err = jest.fn(); 2081e9e3beSEvan Bacon const session = new DevelopmentSession('/', 'http://localhost:19001/', err); 218d307f52SEvan Bacon 228d307f52SEvan Bacon asMock(ProjectDevices.getDevicesInfoAsync).mockResolvedValue({ 238d307f52SEvan Bacon devices: [{ installationId: '123' }, { installationId: '456' }], 248d307f52SEvan Bacon }); 258d307f52SEvan Bacon 268d307f52SEvan Bacon const exp = { 278d307f52SEvan Bacon name: 'my-app', 288d307f52SEvan Bacon slug: 'my-app', 298d307f52SEvan Bacon description: 'my-foo-bar', 308d307f52SEvan Bacon primaryColor: '#4630eb', 318d307f52SEvan Bacon }; 328d307f52SEvan Bacon const runtime = 'native'; 33edc92349SJuwan Wheatley const startScope = nock(getExpoApiBaseUrl()) 348d307f52SEvan Bacon .post('/v2/development-sessions/notify-alive?deviceId=123&deviceId=456') 358d307f52SEvan Bacon .reply(200, ''); 36edc92349SJuwan Wheatley const closeScope = nock(getExpoApiBaseUrl()) 37edc92349SJuwan Wheatley .post('/v2/development-sessions/notify-close?deviceId=123&deviceId=456') 38edc92349SJuwan Wheatley .reply(200, ''); 398d307f52SEvan Bacon 408d307f52SEvan Bacon await session.startAsync({ 418d307f52SEvan Bacon exp, 428d307f52SEvan Bacon runtime, 438d307f52SEvan Bacon }); 44edc92349SJuwan Wheatley 45edc92349SJuwan Wheatley await session.closeAsync(); 46edc92349SJuwan Wheatley 47edc92349SJuwan Wheatley expect(ProjectDevices.getDevicesInfoAsync).toHaveBeenCalledTimes(2); 48edc92349SJuwan Wheatley expect(startScope.isDone()).toBe(true); 49edc92349SJuwan Wheatley expect(closeScope.isDone()).toBe(true); 5081e9e3beSEvan Bacon expect(err).not.toBeCalled(); 5181e9e3beSEvan Bacon }); 5281e9e3beSEvan Bacon 5381e9e3beSEvan Bacon it(`surfaces exceptions that would otherwise be uncaught`, async () => { 5481e9e3beSEvan Bacon const err = jest.fn(); 5581e9e3beSEvan Bacon const session = new DevelopmentSession('/', 'http://localhost:19001/', err); 5681e9e3beSEvan Bacon 5781e9e3beSEvan Bacon asMock(ProjectDevices.getDevicesInfoAsync).mockRejectedValueOnce(new Error('predefined error')); 5881e9e3beSEvan Bacon 5981e9e3beSEvan Bacon const exp = { 6081e9e3beSEvan Bacon name: 'my-app', 6181e9e3beSEvan Bacon slug: 'my-app', 6281e9e3beSEvan Bacon description: 'my-foo-bar', 6381e9e3beSEvan Bacon primaryColor: '#4630eb', 6481e9e3beSEvan Bacon }; 6581e9e3beSEvan Bacon const runtime = 'native'; 6681e9e3beSEvan Bacon 6781e9e3beSEvan Bacon // Does not throw directly 6881e9e3beSEvan Bacon await session.startAsync({ 6981e9e3beSEvan Bacon exp, 7081e9e3beSEvan Bacon runtime, 7181e9e3beSEvan Bacon }); 7281e9e3beSEvan Bacon 7381e9e3beSEvan Bacon expect(err).toBeCalled(); 7481e9e3beSEvan Bacon 7581e9e3beSEvan Bacon // Did not repeat the cycle 7681e9e3beSEvan Bacon expect(session['timeout']).toBe(null); 7781e9e3beSEvan Bacon }); 7881e9e3beSEvan Bacon 7981e9e3beSEvan Bacon it(`gracefully handles server outages`, async () => { 8081e9e3beSEvan Bacon const err = jest.fn(); 8181e9e3beSEvan Bacon const session = new DevelopmentSession('/', 'http://localhost:19001/', err); 8281e9e3beSEvan Bacon 8381e9e3beSEvan Bacon asMock(ProjectDevices.getDevicesInfoAsync).mockResolvedValue({ 8481e9e3beSEvan Bacon devices: [{ installationId: '123' }, { installationId: '456' }], 8581e9e3beSEvan Bacon }); 8681e9e3beSEvan Bacon 8781e9e3beSEvan Bacon const exp = { 8881e9e3beSEvan Bacon name: 'my-app', 8981e9e3beSEvan Bacon slug: 'my-app', 9081e9e3beSEvan Bacon description: 'my-foo-bar', 9181e9e3beSEvan Bacon primaryColor: '#4630eb', 9281e9e3beSEvan Bacon }; 9381e9e3beSEvan Bacon const runtime = 'native'; 9481e9e3beSEvan Bacon 9581e9e3beSEvan Bacon // Server is down 9681e9e3beSEvan Bacon nock(getExpoApiBaseUrl()) 9781e9e3beSEvan Bacon .post('/v2/development-sessions/notify-alive?deviceId=123&deviceId=456') 9881e9e3beSEvan Bacon .reply(500, ''); 9981e9e3beSEvan Bacon 10081e9e3beSEvan Bacon // Does not throw directly 10181e9e3beSEvan Bacon await session.startAsync({ 10281e9e3beSEvan Bacon exp, 10381e9e3beSEvan Bacon runtime, 10481e9e3beSEvan Bacon }); 10581e9e3beSEvan Bacon 10681e9e3beSEvan Bacon expect(err).toBeCalled(); 10781e9e3beSEvan Bacon 10881e9e3beSEvan Bacon // Did not repeat the cycle 10981e9e3beSEvan Bacon expect(session['timeout']).toBe(null); 1108d307f52SEvan Bacon }); 1118d307f52SEvan Bacon}); 112