1import * as TaskManager from 'expo-task-manager'; 2import * as Location from 'expo-location'; 3 4import * as TestUtils from '../TestUtils'; 5 6const DEFINED_TASK_NAME = 'defined task'; 7const UNDEFINED_TASK_NAME = 'undefined task'; 8 9export const name = 'TaskManager'; 10 11export async function test(t) { 12 const shouldSkipTestsRequiringPermissions = await TestUtils.shouldSkipTestsRequiringPermissionsAsync(); 13 const describeWithPermissions = shouldSkipTestsRequiringPermissions ? t.xdescribe : t.describe; 14 const locationOptions = { 15 accuracy: Location.Accuracy.Low, 16 showsBackgroundLocationIndicator: false, 17 }; 18 /* 19 Some of these tests cause Expo to crash on device farm with the following error: 20 "sdkUnversionedTestSuite failed: java.lang.NullPointerException: Attempt to invoke interface method 21 'java.util.Map org.unimodules.interfaces.taskManager.TaskInterface.getOptions()' on a null object reference" 22 23 getOptions() is being called from within LocationTaskConsumer.java in the expo-location module 24 several times without checking for null 25 */ 26 t.describe('TaskManager', () => { 27 t.describe('isTaskDefined()', () => { 28 t.it('returns true if task is defined', () => { 29 t.expect(TaskManager.isTaskDefined(DEFINED_TASK_NAME)).toBe(true); 30 }); 31 t.it('returns false if task is not defined', () => { 32 t.expect(TaskManager.isTaskDefined(UNDEFINED_TASK_NAME)).toBe(false); 33 }); 34 }); 35 36 describeWithPermissions('isTaskRegisteredAsync()', async () => { 37 t.beforeAll(async () => { 38 await Location.startLocationUpdatesAsync(DEFINED_TASK_NAME); 39 }); 40 41 t.it('returns true for registered tasks', async () => { 42 t.expect(await TaskManager.isTaskRegisteredAsync(DEFINED_TASK_NAME)).toBe(true); 43 }); 44 45 t.it('returns false for unregistered tasks', async () => { 46 t.expect(await TaskManager.isTaskRegisteredAsync(UNDEFINED_TASK_NAME)).toBe(false); 47 }); 48 49 t.afterAll(async () => { 50 await Location.stopLocationUpdatesAsync(DEFINED_TASK_NAME); 51 }); 52 }); 53 54 describeWithPermissions('getTaskOptionsAsync()', async () => { 55 let taskOptions; 56 57 t.it('returns null for unregistered tasks', async () => { 58 taskOptions = await TaskManager.getTaskOptionsAsync(DEFINED_TASK_NAME); 59 t.expect(taskOptions).toBe(null); 60 }); 61 62 t.it('returns correct options after register', async () => { 63 await Location.startLocationUpdatesAsync(DEFINED_TASK_NAME, locationOptions); 64 taskOptions = await TaskManager.getTaskOptionsAsync(DEFINED_TASK_NAME); 65 t.expect(taskOptions).toEqual(t.jasmine.objectContaining(locationOptions)); 66 }); 67 68 t.it('returns null when unregistered', async () => { 69 await Location.stopLocationUpdatesAsync(DEFINED_TASK_NAME); 70 taskOptions = await TaskManager.getTaskOptionsAsync(DEFINED_TASK_NAME); 71 t.expect(taskOptions).toBe(null); 72 }); 73 }); 74 75 describeWithPermissions('getRegisteredTasksAsync()', async () => { 76 let registeredTasks; 77 78 t.it('returns empty array if there are no tasks', async () => { 79 registeredTasks = await TaskManager.getRegisteredTasksAsync(); 80 t.expect(registeredTasks).toBeDefined(); 81 t.expect(registeredTasks.length).toBe(0); 82 }); 83 84 t.it('returns correct array after registering the task', async () => { 85 await Location.startLocationUpdatesAsync(DEFINED_TASK_NAME, locationOptions); 86 87 registeredTasks = await TaskManager.getRegisteredTasksAsync(); 88 89 t.expect(registeredTasks).toBeDefined(); 90 t.expect(registeredTasks.length).toBe(1); 91 t.expect(registeredTasks.find(task => task.taskName === DEFINED_TASK_NAME)).toEqual( 92 t.jasmine.objectContaining({ 93 taskName: DEFINED_TASK_NAME, 94 taskType: 'location', 95 options: locationOptions, 96 }) 97 ); 98 }); 99 100 t.afterAll(async () => { 101 await Location.stopLocationUpdatesAsync(DEFINED_TASK_NAME); 102 }); 103 }); 104 105 describeWithPermissions('unregisterAllTasksAsync()', () => { 106 t.it('unregisters tasks correctly', async () => { 107 await Location.startLocationUpdatesAsync(DEFINED_TASK_NAME, locationOptions); 108 await TaskManager.unregisterAllTasksAsync(); 109 110 t.expect(await TaskManager.isTaskRegisteredAsync(DEFINED_TASK_NAME)).toBe(false); 111 t.expect((await TaskManager.getRegisteredTasksAsync()).length).toBe(0); 112 t.expect(await Location.hasStartedLocationUpdatesAsync(DEFINED_TASK_NAME)).toBe(false); 113 }); 114 }); 115 116 describeWithPermissions('rejections', () => { 117 t.it('should reject when trying to unregister task with different consumer', async () => { 118 await Location.startLocationUpdatesAsync(DEFINED_TASK_NAME, locationOptions); 119 120 let error; 121 try { 122 await Location.stopGeofencingAsync(DEFINED_TASK_NAME, locationOptions); 123 } catch (e) { 124 error = e; 125 } 126 t.expect(error).toBeDefined(); 127 t.expect(error.message).toMatch(/Invalid task consumer/); 128 129 await Location.stopLocationUpdatesAsync(DEFINED_TASK_NAME); 130 }); 131 }); 132 }); 133} 134 135// Empty task so we can properly test some methods. 136TaskManager.defineTask(DEFINED_TASK_NAME, () => {}); 137