1import * as Calendar from 'expo-calendar'; 2import { UnavailabilityError } from 'expo-modules-core'; 3import { Platform } from 'react-native'; 4 5import * as TestUtils from '../TestUtils'; 6 7export const name = 'CalendarReminders'; 8 9async function createTestReminderAsync(calendarId) { 10 return await Calendar.createReminderAsync(calendarId, { 11 title: 'Reminder to buy a ticket', 12 startDate: new Date(2019, 3, 3, 9, 0, 0), 13 dueDate: new Date(2019, 3, 3, 23, 59, 59), 14 }); 15} 16 17async function getFirstCalendarForRemindersAsync() { 18 const calendars = await Calendar.getCalendarsAsync(Calendar.EntityTypes.REMINDER); 19 return calendars[0] && calendars[0].id; 20} 21 22function expectMethodsToReject(t, methods) { 23 for (const methodName of methods) { 24 t.describe(`${methodName}()`, () => { 25 t.it('rejects with UnavailabilityError on unsupported platform', async () => { 26 let error; 27 try { 28 await Calendar[methodName](); 29 } catch (e) { 30 error = e; 31 } 32 t.expect(error instanceof UnavailabilityError).toBe(true); 33 t.expect(error.message).toBe(new UnavailabilityError('Calendar', methodName).message); 34 }); 35 }); 36 } 37} 38 39function testReminderShape(t, reminder) { 40 t.expect(reminder).toBeDefined(); 41 t.expect(typeof reminder.id).toBe('string'); 42 t.expect(typeof reminder.calendarId).toBe('string'); 43 t.expect(typeof reminder.title).toBe('string'); 44 // t.expect(typeof reminder.startDate).toBe('string'); 45 // t.expect(typeof reminder.dueDate).toBe('string'); 46 t.expect(typeof reminder.completed).toBe('boolean'); 47} 48 49export async function test(t) { 50 const shouldSkipTestsRequiringPermissions = await TestUtils.shouldSkipTestsRequiringPermissionsAsync(); 51 const describeWithPermissions = shouldSkipTestsRequiringPermissions ? t.xdescribe : t.describe; 52 53 describeWithPermissions('CalendarReminders', () => { 54 if (Platform.OS !== 'ios') { 55 expectMethodsToReject(t, [ 56 'requestRemindersPermissionsAsync', 57 'getRemindersAsync', 58 'getReminderAsync', 59 'createReminderAsync', 60 'updateReminderAsync', 61 'deleteReminderAsync', 62 ]); 63 return; 64 } 65 66 let calendarId = null; 67 68 t.beforeAll(async () => { 69 calendarId = await Calendar.createCalendarAsync({ 70 title: 'Expo Reminders Calendar', 71 entityType: Calendar.EntityTypes.REMINDER, 72 }); 73 }); 74 75 t.describe('requestRemindersPermissionsAsync()', () => { 76 t.it('requests for Reminders permissions', async () => { 77 const results = await Calendar.requestRemindersPermissionsAsync(); 78 79 t.expect(results.granted).toBe(true); 80 t.expect(results.status).toBe('granted'); 81 }); 82 }); 83 84 t.describe('createReminderAsync()', () => { 85 let reminderId; 86 87 t.it('creates a reminder', async () => { 88 reminderId = await createTestReminderAsync(calendarId); 89 90 t.expect(reminderId).toBeDefined(); 91 t.expect(typeof reminderId).toBe('string'); 92 }); 93 94 t.afterAll(async () => { 95 await Calendar.deleteReminderAsync(reminderId); 96 }); 97 }); 98 99 t.describe('getRemindersAsync()', () => { 100 let reminderId; 101 102 t.beforeAll(async () => { 103 reminderId = await createTestReminderAsync(calendarId); 104 }); 105 106 t.it('returns an array of reminders', async () => { 107 const reminders = await Calendar.getRemindersAsync( 108 [calendarId], 109 Calendar.ReminderStatus.INCOMPLETE, 110 new Date(2019, 3, 2), 111 new Date(2019, 3, 5) 112 ); 113 114 t.expect(Array.isArray(reminders)).toBe(true); 115 t.expect(reminders.length).toBe(1); 116 t.expect(reminders[0].id).toBe(reminderId); 117 testReminderShape(t, reminders[0]); 118 }); 119 120 t.afterAll(async () => { 121 await Calendar.deleteReminderAsync(reminderId); 122 }); 123 }); 124 125 t.describe('getReminderAsync()', () => { 126 let reminderId; 127 128 t.beforeAll(async () => { 129 reminderId = await createTestReminderAsync(calendarId); 130 }); 131 132 t.it('returns an array of reminders', async () => { 133 const reminder = await Calendar.getReminderAsync(reminderId); 134 135 t.expect(reminder).toBeDefined(); 136 t.expect(reminder.id).toBe(reminderId); 137 testReminderShape(t, reminder); 138 }); 139 140 t.afterAll(async () => { 141 await Calendar.deleteReminderAsync(reminderId); 142 }); 143 }); 144 145 t.describe('updateReminderAsync()', () => { 146 let reminderId; 147 148 t.beforeAll(async () => { 149 reminderId = await createTestReminderAsync(calendarId); 150 }); 151 152 t.it('updates a reminder', async () => { 153 const dueDate = new Date(); 154 dueDate.setMilliseconds(0); 155 156 const updatedReminderId = await Calendar.updateReminderAsync(reminderId, { dueDate }); 157 const reminder = await Calendar.getReminderAsync(updatedReminderId); 158 159 t.expect(updatedReminderId).toBe(reminderId); 160 t.expect(reminder.dueDate).toBe(dueDate.toISOString()); 161 }); 162 163 t.afterAll(async () => { 164 await Calendar.deleteReminderAsync(reminderId); 165 }); 166 }); 167 168 t.describe('deleteReminderAsync()', () => { 169 let reminderId; 170 171 t.beforeAll(async () => { 172 reminderId = await createTestReminderAsync(calendarId); 173 }); 174 175 t.it('deletes a reminder', async () => { 176 await Calendar.deleteReminderAsync(reminderId); 177 let error; 178 179 try { 180 await Calendar.getReminderAsync(reminderId); 181 } catch (e) { 182 error = e; 183 } 184 t.expect(error).toBeDefined(); 185 t.expect(error instanceof Error).toBe(true); 186 t.expect(error.code).toBe('E_REMINDER_NOT_FOUND'); 187 }); 188 189 t.afterAll(async () => { 190 await Calendar.deleteReminderAsync(reminderId); 191 }); 192 }); 193 194 t.afterAll(async () => { 195 await Calendar.deleteCalendarAsync(calendarId); 196 }); 197 }); 198} 199