AlertServiceTest.java revision 3a07a68da6460c36a5dbec5b8828baa4355dbe04
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.calendar.alerts; 18 19import static android.app.Notification.PRIORITY_DEFAULT; 20import static android.app.Notification.PRIORITY_HIGH; 21import static android.app.Notification.PRIORITY_MIN; 22 23import android.app.AlarmManager; 24import android.app.PendingIntent; 25import android.content.SharedPreferences; 26import android.database.MatrixCursor; 27import android.provider.CalendarContract.Attendees; 28import android.provider.CalendarContract.CalendarAlerts; 29import android.test.AndroidTestCase; 30import android.test.suitebuilder.annotation.SmallTest; 31import android.test.suitebuilder.annotation.Smoke; 32import android.text.format.DateUtils; 33import android.text.format.Time; 34 35import com.android.calendar.GeneralPreferences; 36import com.android.calendar.alerts.AlertService.NotificationInfo; 37import com.android.calendar.alerts.AlertService.NotificationWrapper; 38 39import junit.framework.Assert; 40 41import java.util.ArrayList; 42import java.util.Arrays; 43import java.util.Map; 44import java.util.Set; 45 46public class AlertServiceTest extends AndroidTestCase { 47 48 class MockSharedPreferences implements SharedPreferences { 49 50 /* "always", "silent", depends on ringer mode */ 51 private String mVibrateWhen; 52 private String mRingtone; 53 private Boolean mPopup; 54 55 // Strict mode will fail if a preference key is queried more than once. 56 private boolean mStrict = false; 57 58 MockSharedPreferences() { 59 this(false); 60 } 61 62 MockSharedPreferences(boolean strict) { 63 super(); 64 init(); 65 this.mStrict = strict; 66 } 67 68 void init() { 69 mVibrateWhen = "always"; 70 mRingtone = "/some/cool/ringtone"; 71 mPopup = true; 72 } 73 74 @Override 75 public boolean contains(String key) { 76 if (GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN.equals(key)) { 77 return true; 78 } 79 return false; 80 } 81 82 @Override 83 public boolean getBoolean(String key, boolean defValue) { 84 if (GeneralPreferences.KEY_ALERTS_POPUP.equals(key)) { 85 if (mPopup == null) { 86 Assert.fail(GeneralPreferences.KEY_ALERTS_POPUP + " fetched more than once."); 87 } 88 boolean val = mPopup; 89 if (mStrict) { 90 mPopup = null; 91 } 92 return val; 93 } 94 throw new IllegalArgumentException(); 95 } 96 97 @Override 98 public String getString(String key, String defValue) { 99 if (GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN.equals(key)) { 100 if (mVibrateWhen == null) { 101 Assert.fail(GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN 102 + " fetched more than once."); 103 } 104 String val = mVibrateWhen; 105 if (mStrict) { 106 mVibrateWhen = null; 107 } 108 return val; 109 } 110 if (GeneralPreferences.KEY_ALERTS_RINGTONE.equals(key)) { 111 if (mRingtone == null) { 112 Assert.fail(GeneralPreferences.KEY_ALERTS_RINGTONE 113 + " fetched more than once."); 114 } 115 String val = mRingtone; 116 if (mStrict) { 117 mRingtone = null; 118 } 119 return val; 120 } 121 throw new IllegalArgumentException(); 122 } 123 124 @Override 125 public Map<String, ?> getAll() { 126 throw new IllegalArgumentException(); 127 } 128 129 @Override 130 public Set<String> getStringSet(String key, Set<String> defValues) { 131 throw new IllegalArgumentException(); 132 } 133 134 @Override 135 public int getInt(String key, int defValue) { 136 throw new IllegalArgumentException(); 137 } 138 139 @Override 140 public long getLong(String key, long defValue) { 141 throw new IllegalArgumentException(); 142 } 143 144 @Override 145 public float getFloat(String key, float defValue) { 146 throw new IllegalArgumentException(); 147 } 148 149 @Override 150 public Editor edit() { 151 throw new IllegalArgumentException(); 152 } 153 154 @Override 155 public void registerOnSharedPreferenceChangeListener( 156 OnSharedPreferenceChangeListener listener) { 157 throw new IllegalArgumentException(); 158 } 159 160 @Override 161 public void unregisterOnSharedPreferenceChangeListener( 162 OnSharedPreferenceChangeListener listener) { 163 throw new IllegalArgumentException(); 164 } 165 166 } 167 168 // Created these constants so the test cases are shorter 169 public static final int SCHEDULED = CalendarAlerts.STATE_SCHEDULED; 170 public static final int FIRED = CalendarAlerts.STATE_FIRED; 171 public static final int DISMISSED = CalendarAlerts.STATE_DISMISSED; 172 173 public static final int ACCEPTED = Attendees.ATTENDEE_STATUS_ACCEPTED; 174 public static final int DECLINED = Attendees.ATTENDEE_STATUS_DECLINED; 175 public static final int INVITED = Attendees.ATTENDEE_STATUS_INVITED; 176 public static final int TENTATIVE = Attendees.ATTENDEE_STATUS_TENTATIVE; 177 178 class NotificationInstance { 179 int mAlertId; 180 int[] mAlertIdsInDigest; 181 int mPriority; 182 183 public NotificationInstance(int alertId, int priority) { 184 mAlertId = alertId; 185 mPriority = priority; 186 } 187 188 public NotificationInstance(int[] alertIdsInDigest, int priority) { 189 mAlertIdsInDigest = alertIdsInDigest; 190 mPriority = priority; 191 } 192 } 193 194 class Alert { 195 long mEventId; 196 int mAlertStatus; 197 int mResponseStatus; 198 int mAllDay; 199 long mBegin; 200 long mEnd; 201 int mMinute; 202 long mAlarmTime; 203 204 public Alert(long eventId, int alertStatus, int responseStatus, int allDay, long begin, 205 long end, int minute, long alarmTime) { 206 mEventId = eventId; 207 mAlertStatus = alertStatus; 208 mResponseStatus = responseStatus; 209 mAllDay = allDay; 210 mBegin = begin; 211 mEnd = end; 212 mMinute = minute; 213 mAlarmTime = alarmTime; 214 } 215 216 } 217 218 class AlertsTable { 219 220 ArrayList<Alert> mAlerts = new ArrayList<Alert>(); 221 222 int addAlertRow(long eventId, int alertStatus, int responseStatus, int allDay, long begin, 223 long end, long alarmTime) { 224 Alert a = new Alert(eventId, alertStatus, responseStatus, allDay, begin, end, 225 5 /* minute */, alarmTime); 226 int id = mAlerts.size(); 227 mAlerts.add(a); 228 return id; 229 } 230 231 public MatrixCursor getAlertCursor() { 232 MatrixCursor alertCursor = new MatrixCursor(AlertService.ALERT_PROJECTION); 233 234 int i = 0; 235 for (Alert a : mAlerts) { 236 Object[] ca = { 237 i++, 238 a.mEventId, 239 a.mAlertStatus, 240 "Title" + a.mEventId + " " + a.mMinute, 241 "Loc" + a.mEventId, 242 a.mResponseStatus, 243 a.mAllDay, 244 a.mAlarmTime > 0 ? a.mAlarmTime : a.mBegin - a.mMinute * 60 * 1000, 245 a.mMinute, 246 a.mBegin, 247 a.mEnd, 248 "Desc: " + a.mAlarmTime 249 }; 250 alertCursor.addRow(ca); 251 } 252 return alertCursor; 253 } 254 255 } 256 257 class NotificationTestManager extends NotificationMgr { 258 // Expected notifications 259 NotificationInstance[] mExpectedNotifications; 260 NotificationWrapper[] mActualNotifications; 261 boolean[] mCancelled; 262 263 // CalendarAlerts table 264 private ArrayList<Alert> mAlerts; 265 266 public NotificationTestManager(ArrayList<Alert> alerts, int maxNotifications) { 267 assertEquals(0, AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID); 268 mAlerts = alerts; 269 mExpectedNotifications = new NotificationInstance[maxNotifications + 1]; 270 mActualNotifications = new NotificationWrapper[mExpectedNotifications.length]; 271 mCancelled = new boolean[mExpectedNotifications.length]; 272 } 273 274 public void expectTestNotification(int notificationId, int alertId, int highPriority) { 275 mExpectedNotifications[notificationId] = new NotificationInstance(alertId, 276 highPriority); 277 } 278 279 public void expectTestNotification(int notificationId, int[] alertIds, int priority) { 280 mExpectedNotifications[notificationId] = new NotificationInstance(alertIds, priority); 281 } 282 283 private <T> boolean nullContents(T[] array) { 284 for (T item : array) { 285 if (item != null) { 286 return false; 287 } 288 } 289 return true; 290 } 291 292 public void validateNotificationsAndReset() { 293 if (nullContents(mExpectedNotifications)) { 294 return; 295 } 296 297 String debugStr = printActualNotifications(); 298 for (int id = 0; id < mActualNotifications.length; id++) { 299 NotificationInstance expected = mExpectedNotifications[id]; 300 NotificationWrapper actual = mActualNotifications[id]; 301 if (expected == null) { 302 assertNull("Received unexpected notificationId " + id + debugStr, actual); 303 assertTrue("NotificationId " + id + " should have been cancelled." + debugStr, 304 mCancelled[id]); 305 } else { 306 assertNotNull("Expected notificationId " + id + " but it was not posted." 307 + debugStr, actual); 308 assertFalse("NotificationId " + id + " should not have been cancelled." 309 + debugStr, mCancelled[id]); 310 assertEquals("Priority not as expected for notification " + id + debugStr, 311 expected.mPriority, actual.mNotification.priority); 312 if (expected.mAlertIdsInDigest == null) { 313 Alert a = mAlerts.get(expected.mAlertId); 314 assertEquals("Event ID not expected for notification " + id + debugStr, 315 a.mEventId, actual.mEventId); 316 assertEquals("Begin time not expected for notification " + id + debugStr, 317 a.mBegin, actual.mBegin); 318 assertEquals("End time not expected for notification " + id + debugStr, 319 a.mEnd, actual.mEnd); 320 } else { 321 // Notification should be a digest. 322 assertNotNull("Posted notification not a digest as expected." + debugStr, 323 actual.mNw); 324 assertEquals("Number of notifications in digest not as expected." 325 + debugStr, expected.mAlertIdsInDigest.length, actual.mNw.size()); 326 for (int i = 0; i < actual.mNw.size(); i++) { 327 Alert a = mAlerts.get(expected.mAlertIdsInDigest[i]); 328 assertEquals("Digest item " + i + ": Event ID not as expected" 329 + debugStr, a.mEventId, actual.mNw.get(i).mEventId); 330 assertEquals("Digest item " + i + ": Begin time in digest not expected" 331 + debugStr, a.mBegin, actual.mNw.get(i).mBegin); 332 assertEquals("Digest item " + i + ": End time in digest not expected" 333 + debugStr, a.mEnd, actual.mNw.get(i).mEnd); 334 } 335 } 336 } 337 } 338 339 Arrays.fill(mCancelled, false); 340 Arrays.fill(mExpectedNotifications, null); 341 Arrays.fill(mActualNotifications, null); 342 } 343 344 private String printActualNotifications() { 345 StringBuilder s = new StringBuilder(); 346 s.append("\n\nNotifications actually posted:\n"); 347 for (int i = mActualNotifications.length - 1; i >= 0; i--) { 348 NotificationWrapper actual = mActualNotifications[i]; 349 if (actual == null) { 350 continue; 351 } 352 s.append("Notification " + i + " -- "); 353 s.append("priority:" + actual.mNotification.priority); 354 if (actual.mNw == null) { 355 s.append(", eventId:" + actual.mEventId); 356 } else { 357 s.append(", eventIds:{"); 358 for (int digestIndex = 0; digestIndex < actual.mNw.size(); digestIndex++) { 359 s.append(actual.mNw.get(digestIndex).mEventId + ","); 360 } 361 s.append("}"); 362 } 363 s.append("\n"); 364 } 365 return s.toString(); 366 } 367 368 /////////////////////////////// 369 // NotificationMgr methods 370 @Override 371 public void cancel(int id) { 372 assertTrue("id out of bound: " + id, 0 <= id); 373 assertTrue("id out of bound: " + id, id < mCancelled.length); 374 assertNull("id already used", mActualNotifications[id]); 375 assertFalse("id already used", mCancelled[id]); 376 mCancelled[id] = true; 377 assertNull("Unexpected cancel for id " + id, mExpectedNotifications[id]); 378 } 379 380 public void notify(int id, NotificationWrapper nw) { 381 assertTrue("id out of bound: " + id, 0 <= id); 382 assertTrue("id out of bound: " + id, id < mExpectedNotifications.length); 383 assertNull("id already used: " + id, mActualNotifications[id]); 384 mActualNotifications[id] = nw; 385 } 386 } 387 388 // TODO 389 // Catch updates of new state, notify time, and received time 390 // Test ringer, vibrate, 391 // Test intents, action email 392 393 @Smoke 394 @SmallTest 395 public void testGenerateAlerts_none() { 396 MockSharedPreferences prefs = new MockSharedPreferences(); 397 AlertsTable at = new AlertsTable(); 398 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, 399 AlertService.MAX_NOTIFICATIONS); 400 401 // Test no alert 402 long currentTime = 1000000; 403 AlertService.generateAlerts(mContext, ntm, new MockAlarmManager(mContext), prefs, 404 at.getAlertCursor(), currentTime, AlertService.MAX_NOTIFICATIONS); 405 ntm.validateNotificationsAndReset(); 406 } 407 408 @Smoke 409 @SmallTest 410 public void testGenerateAlerts_single() { 411 MockSharedPreferences prefs = new MockSharedPreferences(); 412 MockAlarmManager alarmMgr = new MockAlarmManager(mContext); 413 AlertsTable at = new AlertsTable(); 414 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, 415 AlertService.MAX_NOTIFICATIONS); 416 417 int id = at.addAlertRow(100, SCHEDULED, ACCEPTED, 0 /* all day */, 1300000, 2300000, 0); 418 419 // Test one up coming alert 420 long currentTime = 1000000; 421 ntm.expectTestNotification(1, id, PRIORITY_HIGH); 422 423 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), currentTime, 424 AlertService.MAX_NOTIFICATIONS); 425 ntm.validateNotificationsAndReset(); // This wipes out notification 426 // tests added so far 427 428 // Test half way into an event 429 currentTime = 2300000; 430 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, id, PRIORITY_MIN); 431 432 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), currentTime, 433 AlertService.MAX_NOTIFICATIONS); 434 ntm.validateNotificationsAndReset(); 435 436 // Test event ended 437 currentTime = 4300000; 438 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, id, PRIORITY_MIN); 439 440 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), currentTime, 441 AlertService.MAX_NOTIFICATIONS); 442 ntm.validateNotificationsAndReset(); 443 } 444 445 @SmallTest 446 public void testGenerateAlerts_multiple() { 447 int maxNotifications = 10; 448 MockSharedPreferences prefs = new MockSharedPreferences(); 449 MockAlarmManager alarmMgr = new MockAlarmManager(mContext); 450 AlertsTable at = new AlertsTable(); 451 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, maxNotifications); 452 453 // Current time - 5:00 454 long currentTime = createTimeInMillis(5, 0); 455 456 // Set up future alerts. The real query implementation sorts by descending start 457 // time so simulate that here with our order of adds to AlertsTable. 458 int id9 = at.addAlertRow(9, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0), 459 createTimeInMillis(10, 0), 0); 460 int id8 = at.addAlertRow(8, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0), 461 createTimeInMillis(9, 0), 0); 462 int id7 = at.addAlertRow(7, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0), 463 createTimeInMillis(8, 0), 0); 464 465 // Set up concurrent alerts (that started recently). 466 int id6 = at.addAlertRow(6, SCHEDULED, ACCEPTED, 0, createTimeInMillis(5, 0), 467 createTimeInMillis(5, 40), 0); 468 int id5 = at.addAlertRow(5, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 55), 469 createTimeInMillis(7, 30), 0); 470 int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 50), 471 createTimeInMillis(4, 50), 0); 472 473 // Set up past alerts. 474 int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(3, 0), 475 createTimeInMillis(4, 0), 0); 476 int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(2, 0), 477 createTimeInMillis(3, 0), 0); 478 int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(1, 0), 479 createTimeInMillis(2, 0), 0); 480 481 // Check posted notifications. The order listed here is the order simulates the 482 // order in the real notification bar (last one posted appears on top), so these 483 // should be lowest start time on top. 484 ntm.expectTestNotification(6, id4, PRIORITY_HIGH); // concurrent 485 ntm.expectTestNotification(5, id5, PRIORITY_HIGH); // concurrent 486 ntm.expectTestNotification(4, id6, PRIORITY_HIGH); // concurrent 487 ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future 488 ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future 489 ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future 490 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 491 new int[] {id3, id2, id1}, PRIORITY_MIN); 492 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 493 currentTime, maxNotifications); 494 ntm.validateNotificationsAndReset(); 495 496 // Increase time by 15 minutes to check that some concurrent events dropped 497 // to the low priority bucket. 498 currentTime = createTimeInMillis(5, 15); 499 ntm.expectTestNotification(4, id5, PRIORITY_HIGH); // concurrent 500 ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future 501 ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future 502 ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future 503 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 504 new int[] {id6, id4, id3, id2, id1}, PRIORITY_MIN); 505 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 506 currentTime, maxNotifications); 507 ntm.validateNotificationsAndReset(); 508 509 // Increase time so some of the previously future ones change state. 510 currentTime = createTimeInMillis(8, 15); 511 ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future 512 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 513 new int[] {id8, id7, id6, id5, id4, id3, id2, id1}, PRIORITY_MIN); 514 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 515 currentTime, maxNotifications); 516 ntm.validateNotificationsAndReset(); 517 } 518 519 @SmallTest 520 public void testGenerateAlerts_maxAlerts() { 521 MockSharedPreferences prefs = new MockSharedPreferences(); 522 MockAlarmManager alarmMgr = new MockAlarmManager(mContext); 523 AlertsTable at = new AlertsTable(); 524 525 // Current time - 5:00 526 long currentTime = createTimeInMillis(5, 0); 527 528 // Set up future alerts. The real query implementation sorts by descending start 529 // time so simulate that here with our order of adds to AlertsTable. 530 int id9 = at.addAlertRow(9, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0), 531 createTimeInMillis(10, 0), 0); 532 int id8 = at.addAlertRow(8, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0), 533 createTimeInMillis(9, 0), 0); 534 int id7 = at.addAlertRow(7, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0), 535 createTimeInMillis(8, 0), 0); 536 537 // Set up concurrent alerts (that started recently). 538 int id6 = at.addAlertRow(6, SCHEDULED, ACCEPTED, 0, createTimeInMillis(5, 0), 539 createTimeInMillis(5, 40), 0); 540 int id5 = at.addAlertRow(5, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 55), 541 createTimeInMillis(7, 30), 0); 542 int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 50), 543 createTimeInMillis(4, 50), 0); 544 545 // Set up past alerts. 546 int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(3, 0), 547 createTimeInMillis(4, 0), 0); 548 int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(2, 0), 549 createTimeInMillis(3, 0), 0); 550 int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(1, 0), 551 createTimeInMillis(2, 0), 0); 552 553 // Test when # alerts = max. 554 int maxNotifications = 6; 555 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, maxNotifications); 556 ntm.expectTestNotification(6, id4, PRIORITY_HIGH); // concurrent 557 ntm.expectTestNotification(5, id5, PRIORITY_HIGH); // concurrent 558 ntm.expectTestNotification(4, id6, PRIORITY_HIGH); // concurrent 559 ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future 560 ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future 561 ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future 562 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 563 new int[] {id3, id2, id1}, PRIORITY_MIN); 564 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 565 currentTime, maxNotifications); 566 ntm.validateNotificationsAndReset(); 567 568 // Test when # alerts > max. 569 maxNotifications = 4; 570 ntm = new NotificationTestManager(at.mAlerts, maxNotifications); 571 ntm.expectTestNotification(4, id4, PRIORITY_HIGH); // concurrent 572 ntm.expectTestNotification(3, id5, PRIORITY_HIGH); // concurrent 573 ntm.expectTestNotification(2, id6, PRIORITY_HIGH); // concurrent 574 ntm.expectTestNotification(1, id7, PRIORITY_HIGH); // future 575 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 576 new int[] {id9, id8, id3, id2, id1}, PRIORITY_MIN); 577 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 578 currentTime, maxNotifications); 579 ntm.validateNotificationsAndReset(); 580 } 581 582 /** 583 * Test that the SharedPreferences are only fetched once for each setting. 584 */ 585 @SmallTest 586 public void testGenerateAlerts_sharedPreferences() { 587 MockSharedPreferences prefs = new MockSharedPreferences(true /* strict mode */); 588 AlertsTable at = new AlertsTable(); 589 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, 590 AlertService.MAX_NOTIFICATIONS); 591 592 // Current time - 5:00 593 long currentTime = createTimeInMillis(5, 0); 594 595 // Set up future alerts. The real query implementation sorts by descending start 596 // time so simulate that here with our order of adds to AlertsTable. 597 at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0), 598 createTimeInMillis(10, 0), 0); 599 at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0), 600 createTimeInMillis(9, 0), 0); 601 at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0), 602 createTimeInMillis(8, 0), 0); 603 604 // If this does not result in a failure (MockSharedPreferences fails for duplicate 605 // queries), then test passes. 606 AlertService.generateAlerts(mContext, ntm, new MockAlarmManager(mContext), prefs, 607 at.getAlertCursor(), currentTime, AlertService.MAX_NOTIFICATIONS); 608 } 609 610 public void testGenerateAlerts_refreshTime() { 611 AlertsTable at = new AlertsTable(); 612 MockSharedPreferences prefs = new MockSharedPreferences(); 613 MockAlarmManager alarmMgr = new MockAlarmManager(mContext); 614 NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, 615 AlertService.MAX_NOTIFICATIONS); 616 617 // Since AlertService.processQuery uses DateUtils.isToday instead of checking against 618 // the passed in currentTime (not worth allocating the extra Time objects to do so), use 619 // today's date for this test. 620 Time now = new Time(); 621 now.setToNow(); 622 int day = now.monthDay; 623 int month = now.month; 624 int year = now.year; 625 Time yesterday = new Time(); 626 yesterday.set(System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS); 627 Time tomorrow = new Time(); 628 tomorrow.set(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS); 629 long allDayStart = Utils.createTimeInMillis(0, 0, 0, day, month, year, Time.TIMEZONE_UTC); 630 631 /* today 10am - 10:30am */ 632 int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, 633 Utils.createTimeInMillis(0, 0, 10, day, month, year, Time.getCurrentTimezone()), 634 Utils.createTimeInMillis(0, 30, 10, day, month, year, Time.getCurrentTimezone()), 635 0); 636 /* today 6am - 6am (0 duration event) */ 637 int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, 638 Utils.createTimeInMillis(0, 0, 6, day, month, year, Time.getCurrentTimezone()), 639 Utils.createTimeInMillis(0, 0, 6, day, month, year, Time.getCurrentTimezone()), 0); 640 /* today allDay */ 641 int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 1, allDayStart, 642 allDayStart + DateUtils.HOUR_IN_MILLIS * 24, 0); 643 /* yesterday 11pm - today 7am (multiday event) */ 644 int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, 645 Utils.createTimeInMillis(0, 0, 23, yesterday.monthDay, yesterday.month, 646 yesterday.year, Time.getCurrentTimezone()), 647 Utils.createTimeInMillis(0, 0, 7, day, month, year, Time.getCurrentTimezone()), 0); 648 649 // Test at midnight - next refresh should be 15 min later (15 min into the all 650 // day event). 651 long currentTime = Utils.createTimeInMillis(0, 0, 0, day, month, year, 652 Time.getCurrentTimezone()); 653 alarmMgr.expectAlarmTime(AlarmManager.RTC, currentTime + 15 * DateUtils.MINUTE_IN_MILLIS); 654 ntm.expectTestNotification(4, id1, PRIORITY_HIGH); 655 ntm.expectTestNotification(3, id2, PRIORITY_HIGH); 656 ntm.expectTestNotification(2, id3, PRIORITY_HIGH); 657 ntm.expectTestNotification(1, id4, PRIORITY_HIGH); 658 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 659 currentTime, AlertService.MAX_NOTIFICATIONS); 660 ntm.validateNotificationsAndReset(); 661 662 // Test at 12:30am - next refresh should be 30 min later (1/4 into event 'id1'). 663 currentTime = Utils.createTimeInMillis(0, 30, 0, day, month, year, 664 Time.getCurrentTimezone()); 665 alarmMgr.expectAlarmTime(AlarmManager.RTC, currentTime + 30 * DateUtils.MINUTE_IN_MILLIS); 666 ntm.expectTestNotification(3, id1, PRIORITY_HIGH); 667 ntm.expectTestNotification(2, id3, PRIORITY_HIGH); 668 ntm.expectTestNotification(1, id4, PRIORITY_HIGH); 669 ntm.expectTestNotification(4, id2, PRIORITY_DEFAULT); 670 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 671 currentTime, AlertService.MAX_NOTIFICATIONS); 672 ntm.validateNotificationsAndReset(); 673 674 // Test at 5:55am - next refresh should be 20 min later (15 min after 'id3'). 675 currentTime = Utils.createTimeInMillis(0, 55, 5, day, month, year, 676 Time.getCurrentTimezone()); 677 alarmMgr.expectAlarmTime(AlarmManager.RTC, currentTime + 20 * DateUtils.MINUTE_IN_MILLIS); 678 ntm.expectTestNotification(2, id3, PRIORITY_HIGH); 679 ntm.expectTestNotification(1, id4, PRIORITY_HIGH); 680 ntm.expectTestNotification(3, id2, PRIORITY_DEFAULT); 681 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, id1, PRIORITY_MIN); 682 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 683 currentTime, AlertService.MAX_NOTIFICATIONS); 684 ntm.validateNotificationsAndReset(); 685 686 // Test at 10:14am - next refresh should be 1 min later (15 min into event 'id4'). 687 currentTime = Utils.createTimeInMillis(0, 14, 10, day, month, year, 688 Time.getCurrentTimezone()); 689 alarmMgr.expectAlarmTime(AlarmManager.RTC, currentTime + 1 * DateUtils.MINUTE_IN_MILLIS); 690 ntm.expectTestNotification(1, id4, PRIORITY_HIGH); 691 ntm.expectTestNotification(2, id2, PRIORITY_DEFAULT); 692 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, new int[] {id3, id1}, 693 PRIORITY_MIN); 694 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 695 currentTime, AlertService.MAX_NOTIFICATIONS); 696 ntm.validateNotificationsAndReset(); 697 698 // Test at 10:15am - next refresh should be tomorrow midnight (end of all day event 'id2'). 699 currentTime = Utils.createTimeInMillis(0, 15, 10, day, month, year, 700 Time.getCurrentTimezone()); 701 alarmMgr.expectAlarmTime(AlarmManager.RTC, Utils.createTimeInMillis(0, 0, 23, 702 tomorrow.monthDay, tomorrow.month, tomorrow.year, Time.getCurrentTimezone())); 703 ntm.expectTestNotification(1, id2, PRIORITY_DEFAULT); 704 ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, 705 new int[] {id4, id3, id1}, PRIORITY_MIN); 706 AlertService.generateAlerts(mContext, ntm, alarmMgr, prefs, at.getAlertCursor(), 707 currentTime, AlertService.MAX_NOTIFICATIONS); 708 ntm.validateNotificationsAndReset(); 709 } 710 711 private NotificationInfo createNotificationInfo(long eventId) { 712 return new NotificationInfo("eventName", "location", "description", 100L, 200L, eventId, 713 false, false); 714 } 715 716 private static long createTimeInMillis(int hour, int minute) { 717 return Utils.createTimeInMillis(0 /* second */, minute, hour, 1 /* day */, 1 /* month */, 718 2012 /* year */, Time.getCurrentTimezone()); 719 } 720 721 @SmallTest 722 public void testProcessQuery_skipDeclinedDismissed() { 723 int declinedEventId = 1; 724 int dismissedEventId = 2; 725 int acceptedEventId = 3; 726 long acceptedStartTime = createTimeInMillis(10, 0); 727 long acceptedEndTime = createTimeInMillis(10, 30); 728 729 AlertsTable at = new AlertsTable(); 730 at.addAlertRow(declinedEventId, SCHEDULED, DECLINED, 0, createTimeInMillis(9, 0), 731 createTimeInMillis(10, 0), 0); 732 at.addAlertRow(dismissedEventId, SCHEDULED, DISMISSED, 0, createTimeInMillis(9, 30), 733 createTimeInMillis(11, 0), 0); 734 at.addAlertRow(acceptedEventId, SCHEDULED, ACCEPTED, 1, acceptedStartTime, acceptedEndTime, 735 0); 736 737 ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>(); 738 ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>(); 739 ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>(); 740 long currentTime = createTimeInMillis(5, 0); 741 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 742 mediumPriority, lowPriority); 743 744 assertEquals(0, lowPriority.size()); 745 assertEquals(0, mediumPriority.size()); 746 assertEquals(1, highPriority.size()); 747 assertEquals(acceptedEventId, highPriority.get(0).eventId); 748 assertEquals(acceptedStartTime, highPriority.get(0).startMillis); 749 assertEquals(acceptedEndTime, highPriority.get(0).endMillis); 750 assertTrue(highPriority.get(0).allDay); 751 } 752 753 @SmallTest 754 public void testProcessQuery_newAlert() { 755 int scheduledAlertEventId = 1; 756 int firedAlertEventId = 2; 757 758 AlertsTable at = new AlertsTable(); 759 at.addAlertRow(scheduledAlertEventId, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0), 760 createTimeInMillis(10, 0), 0); 761 at.addAlertRow(firedAlertEventId, FIRED, ACCEPTED, 0, createTimeInMillis(10, 0), 762 createTimeInMillis(10, 30), 0); 763 764 ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>(); 765 ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>(); 766 ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>(); 767 long currentTime = createTimeInMillis(5, 0); 768 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 769 mediumPriority, lowPriority); 770 771 assertEquals(0, lowPriority.size()); 772 assertEquals(0, mediumPriority.size()); 773 assertEquals(2, highPriority.size()); 774 assertEquals(scheduledAlertEventId, highPriority.get(0).eventId); 775 assertTrue("newAlert should be ON for scheduled alerts", highPriority.get(0).newAlert); 776 assertEquals(firedAlertEventId, highPriority.get(1).eventId); 777 assertFalse("newAlert should be OFF for fired alerts", highPriority.get(1).newAlert); 778 } 779 780 @SmallTest 781 public void testProcessQuery_recurringEvent() { 782 int eventId = 1; 783 long earlierStartTime = createTimeInMillis(10, 0); 784 long laterStartTime = createTimeInMillis(11, 0); 785 786 ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>(); 787 ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>(); 788 ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>(); 789 790 AlertsTable at = new AlertsTable(); 791 at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 0, laterStartTime, 792 laterStartTime + DateUtils.HOUR_IN_MILLIS, 0); 793 at.addAlertRow(eventId, FIRED, ACCEPTED, 0, earlierStartTime, 794 earlierStartTime + DateUtils.HOUR_IN_MILLIS, 0); 795 796 // Both events in the future: the earliest one should be chosen. 797 long currentTime = earlierStartTime - DateUtils.DAY_IN_MILLIS * 5; 798 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 799 mediumPriority, lowPriority); 800 assertEquals(0, lowPriority.size()); 801 assertEquals(0, mediumPriority.size()); 802 assertEquals(1, highPriority.size()); 803 assertEquals("Recurring event with earlier start time expected", earlierStartTime, 804 highPriority.get(0).startMillis); 805 806 // Increment time just past the earlier event: the earlier one should be chosen. 807 highPriority.clear(); 808 currentTime = earlierStartTime + DateUtils.MINUTE_IN_MILLIS * 10; 809 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 810 mediumPriority, lowPriority); 811 assertEquals(0, lowPriority.size()); 812 assertEquals(0, mediumPriority.size()); 813 assertEquals(1, highPriority.size()); 814 assertEquals("Recurring event with earlier start time expected", earlierStartTime, 815 highPriority.get(0).startMillis); 816 817 // Increment time to 15 min past the earlier event: the later one should be chosen. 818 highPriority.clear(); 819 currentTime = earlierStartTime + DateUtils.MINUTE_IN_MILLIS * 15; 820 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 821 mediumPriority, lowPriority); 822 assertEquals(0, lowPriority.size()); 823 assertEquals(0, mediumPriority.size()); 824 assertEquals(1, highPriority.size()); 825 assertEquals("Recurring event with later start time expected", laterStartTime, 826 highPriority.get(0).startMillis); 827 828 // Both events in the past: the later one should be chosen (in the low priority bucket). 829 highPriority.clear(); 830 currentTime = laterStartTime + DateUtils.DAY_IN_MILLIS * 5; 831 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 832 mediumPriority, lowPriority); 833 assertEquals(0, highPriority.size()); 834 assertEquals(0, mediumPriority.size()); 835 assertEquals(1, lowPriority.size()); 836 assertEquals("Recurring event with later start time expected", laterStartTime, 837 lowPriority.get(0).startMillis); 838 } 839 840 @SmallTest 841 public void testProcessQuery_recurringAllDayEvent() { 842 int eventId = 1; 843 long day1 = Utils.createTimeInMillis(0, 0, 0, 1, 5, 2012, Time.TIMEZONE_UTC); 844 long day2 = Utils.createTimeInMillis(0, 0, 0, 2, 5, 2012, Time.TIMEZONE_UTC); 845 846 ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>(); 847 ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>(); 848 ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>(); 849 850 AlertsTable at = new AlertsTable(); 851 at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 1, day2, day2 + DateUtils.HOUR_IN_MILLIS * 24, 852 0); 853 at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 1, day1, day1 + DateUtils.HOUR_IN_MILLIS * 24, 854 0); 855 856 // Both events in the future: the earliest one should be chosen. 857 long currentTime = day1 - DateUtils.DAY_IN_MILLIS * 3; 858 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 859 mediumPriority, lowPriority); 860 assertEquals(0, lowPriority.size()); 861 assertEquals(0, mediumPriority.size()); 862 assertEquals(1, highPriority.size()); 863 assertEquals("Recurring event with earlier start time expected", day1, 864 highPriority.get(0).startMillis); 865 866 // Increment time just past the earlier event (to 12:10am). The earlier one should 867 // be chosen. 868 highPriority.clear(); 869 currentTime = Utils.createTimeInMillis(0, 10, 0, 1, 5, 2012, Time.getCurrentTimezone()); 870 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 871 mediumPriority, lowPriority); 872 assertEquals(0, lowPriority.size()); 873 assertEquals(0, mediumPriority.size()); 874 assertEquals(1, highPriority.size()); 875 assertEquals("Recurring event with earlier start time expected", day1, 876 highPriority.get(0).startMillis); 877 878 // Increment time to 15 min past the earlier event: the later one should be chosen. 879 highPriority.clear(); 880 currentTime = Utils.createTimeInMillis(0, 15, 0, 1, 5, 2012, Time.getCurrentTimezone()); 881 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 882 mediumPriority, lowPriority); 883 assertEquals(0, lowPriority.size()); 884 assertEquals(0, mediumPriority.size()); 885 assertEquals(1, highPriority.size()); 886 assertEquals("Recurring event with earlier start time expected", day2, 887 highPriority.get(0).startMillis); 888 889 // Both events in the past: the later one should be chosen (in the low priority bucket). 890 highPriority.clear(); 891 currentTime = day2 + DateUtils.DAY_IN_MILLIS * 1; 892 AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority, 893 mediumPriority, lowPriority); 894 assertEquals(0, highPriority.size()); 895 assertEquals(0, mediumPriority.size()); 896 assertEquals(1, lowPriority.size()); 897 assertEquals("Recurring event with later start time expected", day2, 898 lowPriority.get(0).startMillis); 899 } 900 901 @SmallTest 902 public void testRedistributeBuckets_withinLimits() throws Exception { 903 int maxNotifications = 3; 904 ArrayList<NotificationInfo> threeItemList = new ArrayList<NotificationInfo>(); 905 threeItemList.add(createNotificationInfo(5)); 906 threeItemList.add(createNotificationInfo(4)); 907 threeItemList.add(createNotificationInfo(3)); 908 909 // Test when max notifications at high priority. 910 ArrayList<NotificationInfo> high = threeItemList; 911 ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>(); 912 ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>(); 913 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 914 assertEquals(3, high.size()); 915 assertEquals(0, medium.size()); 916 assertEquals(0, low.size()); 917 918 // Test when max notifications at medium priority. 919 high = new ArrayList<NotificationInfo>(); 920 medium = threeItemList; 921 low = new ArrayList<NotificationInfo>(); 922 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 923 assertEquals(0, high.size()); 924 assertEquals(3, medium.size()); 925 assertEquals(0, low.size()); 926 927 // Test when max notifications at high and medium priority 928 high = new ArrayList<NotificationInfo>(threeItemList); 929 medium = new ArrayList<NotificationInfo>(); 930 medium.add(high.remove(1)); 931 low = new ArrayList<NotificationInfo>(); 932 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 933 assertEquals(2, high.size()); 934 assertEquals(1, medium.size()); 935 assertEquals(0, low.size()); 936 } 937 938 @SmallTest 939 public void testRedistributeBuckets_tooManyHighPriority() throws Exception { 940 ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>(); 941 ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>(); 942 ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>(); 943 high.add(createNotificationInfo(5)); 944 high.add(createNotificationInfo(4)); 945 high.add(createNotificationInfo(3)); 946 high.add(createNotificationInfo(2)); 947 high.add(createNotificationInfo(1)); 948 949 // Invoke the method under test. 950 int maxNotifications = 3; 951 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 952 953 // Verify some high priority were kicked out. 954 assertEquals(3, high.size()); 955 assertEquals(3, high.get(0).eventId); 956 assertEquals(2, high.get(1).eventId); 957 assertEquals(1, high.get(2).eventId); 958 959 // Verify medium priority untouched. 960 assertEquals(0, medium.size()); 961 962 // Verify the extras went to low priority. 963 assertEquals(2, low.size()); 964 assertEquals(5, low.get(0).eventId); 965 assertEquals(4, low.get(1).eventId); 966 } 967 968 @SmallTest 969 public void testRedistributeBuckets_tooManyMediumPriority() throws Exception { 970 ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>(); 971 ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>(); 972 ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>(); 973 high.add(createNotificationInfo(5)); 974 high.add(createNotificationInfo(4)); 975 medium.add(createNotificationInfo(3)); 976 medium.add(createNotificationInfo(2)); 977 medium.add(createNotificationInfo(1)); 978 979 // Invoke the method under test. 980 int maxNotifications = 3; 981 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 982 983 // Verify high priority untouched. 984 assertEquals(2, high.size()); 985 assertEquals(5, high.get(0).eventId); 986 assertEquals(4, high.get(1).eventId); 987 988 // Verify some medium priority were kicked out (the ones near the end of the 989 // list). 990 assertEquals(1, medium.size()); 991 assertEquals(3, medium.get(0).eventId); 992 993 // Verify the extras went to low priority. 994 assertEquals(2, low.size()); 995 assertEquals(2, low.get(0).eventId); 996 assertEquals(1, low.get(1).eventId); 997 } 998 999 @SmallTest 1000 public void testRedistributeBuckets_tooManyHighMediumPriority() throws Exception { 1001 ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>(); 1002 ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>(); 1003 ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>(); 1004 high.add(createNotificationInfo(8)); 1005 high.add(createNotificationInfo(7)); 1006 high.add(createNotificationInfo(6)); 1007 high.add(createNotificationInfo(5)); 1008 high.add(createNotificationInfo(4)); 1009 medium.add(createNotificationInfo(3)); 1010 medium.add(createNotificationInfo(2)); 1011 medium.add(createNotificationInfo(1)); 1012 1013 // Invoke the method under test. 1014 int maxNotifications = 3; 1015 AlertService.redistributeBuckets(high, medium, low, maxNotifications); 1016 1017 // Verify high priority. 1018 assertEquals(3, high.size()); 1019 assertEquals(6, high.get(0).eventId); 1020 assertEquals(5, high.get(1).eventId); 1021 assertEquals(4, high.get(2).eventId); 1022 1023 // Verify some medium priority. 1024 assertEquals(0, medium.size()); 1025 1026 // Verify low priority. 1027 assertEquals(5, low.size()); 1028 assertEquals(8, low.get(0).eventId); 1029 assertEquals(7, low.get(1).eventId); 1030 assertEquals(3, low.get(2).eventId); 1031 assertEquals(2, low.get(3).eventId); 1032 assertEquals(1, low.get(4).eventId); 1033 } 1034} 1035