125b09db869f377b131052447f62ad02e2505cd87Michael Chan/*
225b09db869f377b131052447f62ad02e2505cd87Michael Chan * Copyright (C) 2012 The Android Open Source Project
325b09db869f377b131052447f62ad02e2505cd87Michael Chan *
425b09db869f377b131052447f62ad02e2505cd87Michael Chan * Licensed under the Apache License, Version 2.0 (the "License"); you may not
525b09db869f377b131052447f62ad02e2505cd87Michael Chan * use this file except in compliance with the License. You may obtain a copy of
625b09db869f377b131052447f62ad02e2505cd87Michael Chan * the License at
725b09db869f377b131052447f62ad02e2505cd87Michael Chan *
825b09db869f377b131052447f62ad02e2505cd87Michael Chan * http://www.apache.org/licenses/LICENSE-2.0
925b09db869f377b131052447f62ad02e2505cd87Michael Chan *
1025b09db869f377b131052447f62ad02e2505cd87Michael Chan * Unless required by applicable law or agreed to in writing, software
1125b09db869f377b131052447f62ad02e2505cd87Michael Chan * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1225b09db869f377b131052447f62ad02e2505cd87Michael Chan * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1325b09db869f377b131052447f62ad02e2505cd87Michael Chan * License for the specific language governing permissions and limitations under
1425b09db869f377b131052447f62ad02e2505cd87Michael Chan * the License.
1525b09db869f377b131052447f62ad02e2505cd87Michael Chan */
1625b09db869f377b131052447f62ad02e2505cd87Michael Chan
1725b09db869f377b131052447f62ad02e2505cd87Michael Chanpackage com.android.calendar.alerts;
1825b09db869f377b131052447f62ad02e2505cd87Michael Chan
1925b09db869f377b131052447f62ad02e2505cd87Michael Chanimport static android.app.Notification.PRIORITY_DEFAULT;
2025b09db869f377b131052447f62ad02e2505cd87Michael Chanimport static android.app.Notification.PRIORITY_HIGH;
2125b09db869f377b131052447f62ad02e2505cd87Michael Chanimport static android.app.Notification.PRIORITY_MIN;
2225b09db869f377b131052447f62ad02e2505cd87Michael Chan
2325b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.content.SharedPreferences;
2425b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.database.MatrixCursor;
2525b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.provider.CalendarContract.Attendees;
2625b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.provider.CalendarContract.CalendarAlerts;
2725b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.test.AndroidTestCase;
2825b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.test.suitebuilder.annotation.SmallTest;
2925b09db869f377b131052447f62ad02e2505cd87Michael Chanimport android.test.suitebuilder.annotation.Smoke;
30bce26a2a19499790595e48ca36b43eb130e4a3fbSara Tingimport android.text.format.DateUtils;
31bce26a2a19499790595e48ca36b43eb130e4a3fbSara Tingimport android.text.format.Time;
3225b09db869f377b131052447f62ad02e2505cd87Michael Chan
3325b09db869f377b131052447f62ad02e2505cd87Michael Chanimport com.android.calendar.GeneralPreferences;
3421af116207d5728a312e534b898933bb07f96292Sara Tingimport com.android.calendar.alerts.AlertService.NotificationInfo;
3525b09db869f377b131052447f62ad02e2505cd87Michael Chanimport com.android.calendar.alerts.AlertService.NotificationWrapper;
3625b09db869f377b131052447f62ad02e2505cd87Michael Chan
37b5a2a61208857805cc053c6ac476d30100289279Sara Tingimport junit.framework.Assert;
38b5a2a61208857805cc053c6ac476d30100289279Sara Ting
3925b09db869f377b131052447f62ad02e2505cd87Michael Chanimport java.util.ArrayList;
4025b09db869f377b131052447f62ad02e2505cd87Michael Chanimport java.util.Arrays;
4125b09db869f377b131052447f62ad02e2505cd87Michael Chanimport java.util.Map;
4225b09db869f377b131052447f62ad02e2505cd87Michael Chanimport java.util.Set;
4325b09db869f377b131052447f62ad02e2505cd87Michael Chan
4425b09db869f377b131052447f62ad02e2505cd87Michael Chanpublic class AlertServiceTest extends AndroidTestCase {
4525b09db869f377b131052447f62ad02e2505cd87Michael Chan
4625b09db869f377b131052447f62ad02e2505cd87Michael Chan    class MockSharedPreferences implements SharedPreferences {
4725b09db869f377b131052447f62ad02e2505cd87Michael Chan
4825b09db869f377b131052447f62ad02e2505cd87Michael Chan        /* "always", "silent", depends on ringer mode */
49b5a2a61208857805cc053c6ac476d30100289279Sara Ting        private String mVibrateWhen;
50b5a2a61208857805cc053c6ac476d30100289279Sara Ting        private String mRingtone;
51b5a2a61208857805cc053c6ac476d30100289279Sara Ting        private Boolean mPopup;
52b5a2a61208857805cc053c6ac476d30100289279Sara Ting
53b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Strict mode will fail if a preference key is queried more than once.
54b5a2a61208857805cc053c6ac476d30100289279Sara Ting        private boolean mStrict = false;
55b5a2a61208857805cc053c6ac476d30100289279Sara Ting
56b5a2a61208857805cc053c6ac476d30100289279Sara Ting        MockSharedPreferences() {
57b5a2a61208857805cc053c6ac476d30100289279Sara Ting            this(false);
58b5a2a61208857805cc053c6ac476d30100289279Sara Ting        }
59b5a2a61208857805cc053c6ac476d30100289279Sara Ting
60b5a2a61208857805cc053c6ac476d30100289279Sara Ting        MockSharedPreferences(boolean strict) {
61b5a2a61208857805cc053c6ac476d30100289279Sara Ting            super();
62b5a2a61208857805cc053c6ac476d30100289279Sara Ting            init();
63b5a2a61208857805cc053c6ac476d30100289279Sara Ting            this.mStrict = strict;
64b5a2a61208857805cc053c6ac476d30100289279Sara Ting        }
65b5a2a61208857805cc053c6ac476d30100289279Sara Ting
66b5a2a61208857805cc053c6ac476d30100289279Sara Ting        void init() {
67b5a2a61208857805cc053c6ac476d30100289279Sara Ting            mVibrateWhen = "always";
68b5a2a61208857805cc053c6ac476d30100289279Sara Ting            mRingtone = "/some/cool/ringtone";
69b5a2a61208857805cc053c6ac476d30100289279Sara Ting            mPopup = true;
70b5a2a61208857805cc053c6ac476d30100289279Sara Ting        }
7125b09db869f377b131052447f62ad02e2505cd87Michael Chan
7225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
7325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public boolean contains(String key) {
7425b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN.equals(key)) {
7525b09db869f377b131052447f62ad02e2505cd87Michael Chan                return true;
7625b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
7725b09db869f377b131052447f62ad02e2505cd87Michael Chan            return false;
7825b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
7925b09db869f377b131052447f62ad02e2505cd87Michael Chan
8025b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
8125b09db869f377b131052447f62ad02e2505cd87Michael Chan        public boolean getBoolean(String key, boolean defValue) {
8225b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (GeneralPreferences.KEY_ALERTS_POPUP.equals(key)) {
83b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mPopup == null) {
84b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    Assert.fail(GeneralPreferences.KEY_ALERTS_POPUP + " fetched more than once.");
85b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
86b5a2a61208857805cc053c6ac476d30100289279Sara Ting                boolean val = mPopup;
87b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mStrict) {
88b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    mPopup = null;
89b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
90b5a2a61208857805cc053c6ac476d30100289279Sara Ting                return val;
9125b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
9225b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
9325b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
9425b09db869f377b131052447f62ad02e2505cd87Michael Chan
9525b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
9625b09db869f377b131052447f62ad02e2505cd87Michael Chan        public String getString(String key, String defValue) {
9725b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN.equals(key)) {
98b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mVibrateWhen == null) {
99b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    Assert.fail(GeneralPreferences.KEY_ALERTS_VIBRATE_WHEN
100b5a2a61208857805cc053c6ac476d30100289279Sara Ting                            + " fetched more than once.");
101b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
102b5a2a61208857805cc053c6ac476d30100289279Sara Ting                String val = mVibrateWhen;
103b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mStrict) {
104b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    mVibrateWhen = null;
105b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
106b5a2a61208857805cc053c6ac476d30100289279Sara Ting                return val;
10725b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
10825b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (GeneralPreferences.KEY_ALERTS_RINGTONE.equals(key)) {
109b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mRingtone == null) {
110b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    Assert.fail(GeneralPreferences.KEY_ALERTS_RINGTONE
111b5a2a61208857805cc053c6ac476d30100289279Sara Ting                            + " fetched more than once.");
112b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
113b5a2a61208857805cc053c6ac476d30100289279Sara Ting                String val = mRingtone;
114b5a2a61208857805cc053c6ac476d30100289279Sara Ting                if (mStrict) {
115b5a2a61208857805cc053c6ac476d30100289279Sara Ting                    mRingtone = null;
116b5a2a61208857805cc053c6ac476d30100289279Sara Ting                }
117b5a2a61208857805cc053c6ac476d30100289279Sara Ting                return val;
11825b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
11925b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
12025b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
12125b09db869f377b131052447f62ad02e2505cd87Michael Chan
12225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
12325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public Map<String, ?> getAll() {
12425b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
12525b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
12625b09db869f377b131052447f62ad02e2505cd87Michael Chan
12725b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
12825b09db869f377b131052447f62ad02e2505cd87Michael Chan        public Set<String> getStringSet(String key, Set<String> defValues) {
12925b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
13025b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
13125b09db869f377b131052447f62ad02e2505cd87Michael Chan
13225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
13325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public int getInt(String key, int defValue) {
13425b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
13525b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
13625b09db869f377b131052447f62ad02e2505cd87Michael Chan
13725b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
13825b09db869f377b131052447f62ad02e2505cd87Michael Chan        public long getLong(String key, long defValue) {
13925b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
14025b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
14125b09db869f377b131052447f62ad02e2505cd87Michael Chan
14225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
14325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public float getFloat(String key, float defValue) {
14425b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
14525b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
14625b09db869f377b131052447f62ad02e2505cd87Michael Chan
14725b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
14825b09db869f377b131052447f62ad02e2505cd87Michael Chan        public Editor edit() {
14925b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
15025b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
15125b09db869f377b131052447f62ad02e2505cd87Michael Chan
15225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
15325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void registerOnSharedPreferenceChangeListener(
15425b09db869f377b131052447f62ad02e2505cd87Michael Chan                OnSharedPreferenceChangeListener listener) {
15525b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
15625b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
15725b09db869f377b131052447f62ad02e2505cd87Michael Chan
15825b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
15925b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void unregisterOnSharedPreferenceChangeListener(
16025b09db869f377b131052447f62ad02e2505cd87Michael Chan                OnSharedPreferenceChangeListener listener) {
16125b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
16225b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
16325b09db869f377b131052447f62ad02e2505cd87Michael Chan
16425b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
16525b09db869f377b131052447f62ad02e2505cd87Michael Chan
16625b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Created these constants so the test cases are shorter
16725b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int SCHEDULED = CalendarAlerts.STATE_SCHEDULED;
16825b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int FIRED = CalendarAlerts.STATE_FIRED;
16925b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int DISMISSED = CalendarAlerts.STATE_DISMISSED;
17025b09db869f377b131052447f62ad02e2505cd87Michael Chan
17125b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int ACCEPTED = Attendees.ATTENDEE_STATUS_ACCEPTED;
17225b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int DECLINED = Attendees.ATTENDEE_STATUS_DECLINED;
17325b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int INVITED = Attendees.ATTENDEE_STATUS_INVITED;
17425b09db869f377b131052447f62ad02e2505cd87Michael Chan    public static final int TENTATIVE = Attendees.ATTENDEE_STATUS_TENTATIVE;
17525b09db869f377b131052447f62ad02e2505cd87Michael Chan
17625b09db869f377b131052447f62ad02e2505cd87Michael Chan    class NotificationInstance {
17725b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mAlertId;
178bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int[] mAlertIdsInDigest;
17925b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mPriority;
18025b09db869f377b131052447f62ad02e2505cd87Michael Chan
18125b09db869f377b131052447f62ad02e2505cd87Michael Chan        public NotificationInstance(int alertId, int priority) {
18225b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAlertId = alertId;
18325b09db869f377b131052447f62ad02e2505cd87Michael Chan            mPriority = priority;
18425b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
185bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
186bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        public NotificationInstance(int[] alertIdsInDigest, int priority) {
187bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            mAlertIdsInDigest = alertIdsInDigest;
188bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            mPriority = priority;
189bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        }
19025b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
19125b09db869f377b131052447f62ad02e2505cd87Michael Chan
19225b09db869f377b131052447f62ad02e2505cd87Michael Chan    class Alert {
19325b09db869f377b131052447f62ad02e2505cd87Michael Chan        long mEventId;
19425b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mAlertStatus;
19525b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mResponseStatus;
19625b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mAllDay;
19725b09db869f377b131052447f62ad02e2505cd87Michael Chan        long mBegin;
19825b09db869f377b131052447f62ad02e2505cd87Michael Chan        long mEnd;
19925b09db869f377b131052447f62ad02e2505cd87Michael Chan        int mMinute;
20025b09db869f377b131052447f62ad02e2505cd87Michael Chan        long mAlarmTime;
20125b09db869f377b131052447f62ad02e2505cd87Michael Chan
20225b09db869f377b131052447f62ad02e2505cd87Michael Chan        public Alert(long eventId, int alertStatus, int responseStatus, int allDay, long begin,
20325b09db869f377b131052447f62ad02e2505cd87Michael Chan                long end, int minute, long alarmTime) {
20425b09db869f377b131052447f62ad02e2505cd87Michael Chan            mEventId = eventId;
20525b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAlertStatus = alertStatus;
20625b09db869f377b131052447f62ad02e2505cd87Michael Chan            mResponseStatus = responseStatus;
20725b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAllDay = allDay;
20825b09db869f377b131052447f62ad02e2505cd87Michael Chan            mBegin = begin;
20925b09db869f377b131052447f62ad02e2505cd87Michael Chan            mEnd = end;
21025b09db869f377b131052447f62ad02e2505cd87Michael Chan            mMinute = minute;
21125b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAlarmTime = alarmTime;
21225b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
21325b09db869f377b131052447f62ad02e2505cd87Michael Chan
21425b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
21525b09db869f377b131052447f62ad02e2505cd87Michael Chan
21625b09db869f377b131052447f62ad02e2505cd87Michael Chan    class AlertsTable {
21725b09db869f377b131052447f62ad02e2505cd87Michael Chan
21825b09db869f377b131052447f62ad02e2505cd87Michael Chan        ArrayList<Alert> mAlerts = new ArrayList<Alert>();
21925b09db869f377b131052447f62ad02e2505cd87Michael Chan
22025b09db869f377b131052447f62ad02e2505cd87Michael Chan        int addAlertRow(long eventId, int alertStatus, int responseStatus, int allDay, long begin,
221bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                long end, long alarmTime) {
222bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            Alert a = new Alert(eventId, alertStatus, responseStatus, allDay, begin, end,
223bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    5 /* minute */, alarmTime);
22425b09db869f377b131052447f62ad02e2505cd87Michael Chan            int id = mAlerts.size();
22525b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAlerts.add(a);
22625b09db869f377b131052447f62ad02e2505cd87Michael Chan            return id;
22725b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
22825b09db869f377b131052447f62ad02e2505cd87Michael Chan
22925b09db869f377b131052447f62ad02e2505cd87Michael Chan        public MatrixCursor getAlertCursor() {
23025b09db869f377b131052447f62ad02e2505cd87Michael Chan            MatrixCursor alertCursor = new MatrixCursor(AlertService.ALERT_PROJECTION);
23125b09db869f377b131052447f62ad02e2505cd87Michael Chan
23225b09db869f377b131052447f62ad02e2505cd87Michael Chan            int i = 0;
23325b09db869f377b131052447f62ad02e2505cd87Michael Chan            for (Alert a : mAlerts) {
23425b09db869f377b131052447f62ad02e2505cd87Michael Chan                Object[] ca = {
23525b09db869f377b131052447f62ad02e2505cd87Michael Chan                        i++,
23625b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mEventId,
23725b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mAlertStatus,
23825b09db869f377b131052447f62ad02e2505cd87Michael Chan                        "Title" + a.mEventId + " " + a.mMinute,
23925b09db869f377b131052447f62ad02e2505cd87Michael Chan                        "Loc" + a.mEventId,
24025b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mResponseStatus,
24125b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mAllDay,
24225b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mAlarmTime > 0 ? a.mAlarmTime : a.mBegin - a.mMinute * 60 * 1000,
24325b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mMinute,
24425b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mBegin,
24525b09db869f377b131052447f62ad02e2505cd87Michael Chan                        a.mEnd,
24625b09db869f377b131052447f62ad02e2505cd87Michael Chan                        "Desc: " + a.mAlarmTime
24725b09db869f377b131052447f62ad02e2505cd87Michael Chan                };
24825b09db869f377b131052447f62ad02e2505cd87Michael Chan                alertCursor.addRow(ca);
24925b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
25025b09db869f377b131052447f62ad02e2505cd87Michael Chan            return alertCursor;
25125b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
25225b09db869f377b131052447f62ad02e2505cd87Michael Chan
25325b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
25425b09db869f377b131052447f62ad02e2505cd87Michael Chan
25525b09db869f377b131052447f62ad02e2505cd87Michael Chan    class NotificationTestManager implements NotificationMgr {
25625b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Expected notifications
257bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        NotificationInstance[] mNotifications;
25825b09db869f377b131052447f62ad02e2505cd87Michael Chan
25925b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Flag to know which notification has been posted or canceled
26025b09db869f377b131052447f62ad02e2505cd87Michael Chan        boolean[] mDone;
26125b09db869f377b131052447f62ad02e2505cd87Michael Chan
26225b09db869f377b131052447f62ad02e2505cd87Michael Chan        // CalendarAlerts table
26325b09db869f377b131052447f62ad02e2505cd87Michael Chan        private ArrayList<Alert> mAlerts;
26425b09db869f377b131052447f62ad02e2505cd87Michael Chan
265bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        public NotificationTestManager(ArrayList<Alert> alerts, int maxNotifications) {
26625b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertEquals(0, AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID);
26725b09db869f377b131052447f62ad02e2505cd87Michael Chan            mAlerts = alerts;
268bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            mNotifications = new NotificationInstance[maxNotifications + 1];
26925b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
27025b09db869f377b131052447f62ad02e2505cd87Michael Chan
27125b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void expectTestNotification(int notificationId, int alertId, int highPriority) {
27225b09db869f377b131052447f62ad02e2505cd87Michael Chan            mNotifications[notificationId] = new NotificationInstance(alertId, highPriority);
27325b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
27425b09db869f377b131052447f62ad02e2505cd87Michael Chan
275bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        public void expectTestNotification(int notificationId, int[] alertIds, int priority) {
276bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            mNotifications[notificationId] = new NotificationInstance(alertIds, priority);
277bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        }
278bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
27925b09db869f377b131052447f62ad02e2505cd87Michael Chan        private void verifyNotification(int id, NotificationWrapper nw) {
280bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                assertEquals(mNotifications[id].mPriority, nw.mNotification.priority);
281bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
282bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                NotificationInstance expected = mNotifications[id];
283bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                if (expected.mAlertIdsInDigest == null) {
284bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    Alert a = mAlerts.get(expected.mAlertId);
285bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    assertEquals("Event ID", a.mEventId, nw.mEventId);
286bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    assertEquals("Begin time", a.mBegin, nw.mBegin);
287bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    assertEquals("End time", a.mEnd, nw.mEnd);
288bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                } else {
289bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    // Notification should be a digest.
290bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    assertNotNull("Posted notification not a digest as expected.", nw.mNw);
291bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    assertEquals("Number of notifications in digest not as expected.",
292bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                            expected.mAlertIdsInDigest.length, nw.mNw.size());
293bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    for (int i = 0; i < nw.mNw.size(); i++) {
294bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                        Alert a = mAlerts.get(expected.mAlertIdsInDigest[i]);
295bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                        assertEquals("Digest item " + i + ": Event ID not as expected",
296bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                                a.mEventId, nw.mNw.get(i).mEventId);
297bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                        assertEquals("Digest item " + i + ": Begin time in digest",
298bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                                a.mBegin, nw.mNw.get(i).mBegin);
299bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                        assertEquals("Digest item " + i + ": End time in digest",
300bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                                a.mEnd, nw.mNw.get(i).mEnd);
301bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                    }
302bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                }
30325b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
30425b09db869f377b131052447f62ad02e2505cd87Michael Chan
30525b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void validateNotificationsAndReset() {
30625b09db869f377b131052447f62ad02e2505cd87Michael Chan            for (int i = 0; i < mDone.length; i++) {
30725b09db869f377b131052447f62ad02e2505cd87Michael Chan                assertTrue("Notification id " + i + " has not been posted", mDone[i]);
30825b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
30925b09db869f377b131052447f62ad02e2505cd87Michael Chan            Arrays.fill(mDone, false);
31025b09db869f377b131052447f62ad02e2505cd87Michael Chan            Arrays.fill(mNotifications, null);
31125b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
31225b09db869f377b131052447f62ad02e2505cd87Michael Chan
31325b09db869f377b131052447f62ad02e2505cd87Michael Chan        ///////////////////////////////
31425b09db869f377b131052447f62ad02e2505cd87Michael Chan        // NotificationMgr methods
31525b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
31625b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void cancel(int id) {
31725b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (mDone == null) {
31825b09db869f377b131052447f62ad02e2505cd87Michael Chan                mDone = new boolean[mNotifications.length];
31925b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
32025b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertTrue("id out of bound: " + id, 0 <= id);
32125b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertTrue("id out of bound: " + id, id < mDone.length);
32225b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertFalse("id already used", mDone[id]);
32325b09db869f377b131052447f62ad02e2505cd87Michael Chan            mDone[id] = true;
32425b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertNull("Unexpected cancel for id " + id, mNotifications[id]);
32525b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
32625b09db869f377b131052447f62ad02e2505cd87Michael Chan
32725b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
32825b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void cancel(String tag, int id) {
32925b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
33025b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
33125b09db869f377b131052447f62ad02e2505cd87Michael Chan
33225b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
33325b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void cancelAll() {
33425b09db869f377b131052447f62ad02e2505cd87Michael Chan            for (int i = 0; i < mNotifications.length; i++) {
33525b09db869f377b131052447f62ad02e2505cd87Michael Chan                assertNull("Expecting notification id " + i + ". Got cancelAll", mNotifications[i]);
33625b09db869f377b131052447f62ad02e2505cd87Michael Chan
33725b09db869f377b131052447f62ad02e2505cd87Michael Chan                if (mDone != null) {
33825b09db869f377b131052447f62ad02e2505cd87Michael Chan                    assertFalse("Notification id " + i + " is done but got cancelAll", mDone[i]);
33925b09db869f377b131052447f62ad02e2505cd87Michael Chan                }
34025b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
34125b09db869f377b131052447f62ad02e2505cd87Michael Chan
34225b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertNull(mDone); // this should have been null since nothing
34325b09db869f377b131052447f62ad02e2505cd87Michael Chan                               // should have been posted
34425b09db869f377b131052447f62ad02e2505cd87Michael Chan            mDone = new boolean[mNotifications.length];
34525b09db869f377b131052447f62ad02e2505cd87Michael Chan            Arrays.fill(mDone, true);
34625b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
34725b09db869f377b131052447f62ad02e2505cd87Michael Chan
34825b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
34925b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void notify(int id, NotificationWrapper nw) {
35025b09db869f377b131052447f62ad02e2505cd87Michael Chan            if (mDone == null) {
35125b09db869f377b131052447f62ad02e2505cd87Michael Chan                mDone = new boolean[mNotifications.length];
35225b09db869f377b131052447f62ad02e2505cd87Michael Chan            }
35325b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertTrue("id out of bound: " + id, 0 <= id);
35425b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertTrue("id out of bound: " + id, id < mDone.length);
35525b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertFalse("id already used", mDone[id]);
35625b09db869f377b131052447f62ad02e2505cd87Michael Chan            mDone[id] = true;
35725b09db869f377b131052447f62ad02e2505cd87Michael Chan
35825b09db869f377b131052447f62ad02e2505cd87Michael Chan            assertNotNull("Unexpected notify for id " + id, mNotifications[id]);
35925b09db869f377b131052447f62ad02e2505cd87Michael Chan
36025b09db869f377b131052447f62ad02e2505cd87Michael Chan            verifyNotification(id, nw);
36125b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
36225b09db869f377b131052447f62ad02e2505cd87Michael Chan
36325b09db869f377b131052447f62ad02e2505cd87Michael Chan        @Override
36425b09db869f377b131052447f62ad02e2505cd87Michael Chan        public void notify(String tag, int id, NotificationWrapper nw) {
36525b09db869f377b131052447f62ad02e2505cd87Michael Chan            throw new IllegalArgumentException();
36625b09db869f377b131052447f62ad02e2505cd87Michael Chan        }
36725b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
36825b09db869f377b131052447f62ad02e2505cd87Michael Chan
36925b09db869f377b131052447f62ad02e2505cd87Michael Chan    // TODO
37025b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Catch updates of new state, notify time, and received time
37125b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Test ringer, vibrate,
37225b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Test digest notifications
37325b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Test intents, action email
37425b09db869f377b131052447f62ad02e2505cd87Michael Chan    // Catch alarmmgr calls
37525b09db869f377b131052447f62ad02e2505cd87Michael Chan
37625b09db869f377b131052447f62ad02e2505cd87Michael Chan    @Smoke
37725b09db869f377b131052447f62ad02e2505cd87Michael Chan    @SmallTest
37825b09db869f377b131052447f62ad02e2505cd87Michael Chan    public void testNoAlerts() {
37925b09db869f377b131052447f62ad02e2505cd87Michael Chan        MockSharedPreferences prefs = new MockSharedPreferences();
38025b09db869f377b131052447f62ad02e2505cd87Michael Chan        AlertsTable at = new AlertsTable();
381bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        NotificationTestManager ntm = new NotificationTestManager(at.mAlerts,
382bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
38325b09db869f377b131052447f62ad02e2505cd87Michael Chan
38425b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Test no alert
38525b09db869f377b131052447f62ad02e2505cd87Michael Chan        long currentTime = 1000000;
386bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
387bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
38825b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.validateNotificationsAndReset();
38925b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
39025b09db869f377b131052447f62ad02e2505cd87Michael Chan
39125b09db869f377b131052447f62ad02e2505cd87Michael Chan    @Smoke
39225b09db869f377b131052447f62ad02e2505cd87Michael Chan    @SmallTest
39325b09db869f377b131052447f62ad02e2505cd87Michael Chan    public void testSingleAlert() {
39425b09db869f377b131052447f62ad02e2505cd87Michael Chan        MockSharedPreferences prefs = new MockSharedPreferences();
39525b09db869f377b131052447f62ad02e2505cd87Michael Chan        AlertsTable at = new AlertsTable();
396bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        NotificationTestManager ntm = new NotificationTestManager(at.mAlerts,
397bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
39825b09db869f377b131052447f62ad02e2505cd87Michael Chan
399bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id = at.addAlertRow(100, SCHEDULED, ACCEPTED, 0 /* all day */, 1300000, 2300000, 0);
40025b09db869f377b131052447f62ad02e2505cd87Michael Chan
40125b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Test one up coming alert
40225b09db869f377b131052447f62ad02e2505cd87Michael Chan        long currentTime = 1000000;
40325b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.expectTestNotification(1, id, PRIORITY_HIGH);
40425b09db869f377b131052447f62ad02e2505cd87Michael Chan
405bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
406bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
40725b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.validateNotificationsAndReset(); // This wipes out notification
40825b09db869f377b131052447f62ad02e2505cd87Michael Chan                                             // tests added so far
40925b09db869f377b131052447f62ad02e2505cd87Michael Chan
41025b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Test half way into an event
41125b09db869f377b131052447f62ad02e2505cd87Michael Chan        currentTime = 2300000;
41225b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, id, PRIORITY_DEFAULT);
41325b09db869f377b131052447f62ad02e2505cd87Michael Chan
414bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
415bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
41625b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.validateNotificationsAndReset();
41725b09db869f377b131052447f62ad02e2505cd87Michael Chan
41825b09db869f377b131052447f62ad02e2505cd87Michael Chan        // Test event ended
41925b09db869f377b131052447f62ad02e2505cd87Michael Chan        currentTime = 4300000;
42025b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, id, PRIORITY_MIN);
42125b09db869f377b131052447f62ad02e2505cd87Michael Chan
422bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
423bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                AlertService.MAX_NOTIFICATIONS);
424bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.validateNotificationsAndReset();
425bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
426bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
427bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
428bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testMultipleAlerts() {
429bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int maxNotifications = 10;
430bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        MockSharedPreferences prefs = new MockSharedPreferences();
431bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
432bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, maxNotifications);
433bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
434bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Current time - 5:00
435bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = createTimeInMillis(5, 0);
436bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
437bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up future alerts.  The real query implementation sorts by descending start
438bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // time so simulate that here with our order of adds to AlertsTable.
439bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id9 = at.addAlertRow(9, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0),
440bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(10, 0), 0);
441bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id8 = at.addAlertRow(8, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0),
442bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(9, 0), 0);
443bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id7 = at.addAlertRow(7, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0),
444bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(8, 0), 0);
445bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
446bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up concurrent alerts (that started recently).
447bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id6 = at.addAlertRow(6, SCHEDULED, ACCEPTED, 0, createTimeInMillis(5, 0),
448bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(5, 40), 0);
449bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id5 = at.addAlertRow(5, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 55),
450bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(7, 30), 0);
451bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 50),
452bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(4, 50), 0);
453bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
454bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up past alerts.
455bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(3, 0),
456bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(4, 0), 0);
457bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(2, 0),
458bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(3, 0), 0);
459bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(1, 0),
460bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(2, 0), 0);
461bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
462bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Check posted notifications.  The order listed here is the order simulates the
463bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // order in the real notification bar (last one posted appears on top), so these
464bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // should be lowest start time on top.
465bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(6, id4, PRIORITY_HIGH); // concurrent
466bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(5, id5, PRIORITY_HIGH); // concurrent
467bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(4, id6, PRIORITY_HIGH); // concurrent
468bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future
469bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future
470bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future
471bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
472bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                new int[] {id3, id2, id1}, PRIORITY_MIN);
473bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
474bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                maxNotifications);
475bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.validateNotificationsAndReset();
476bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
477bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increase time by 15 minutes to check that some concurrent events dropped
478bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // to the low priority bucket.
479bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = createTimeInMillis(5, 15);
480bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(4, id5, PRIORITY_HIGH); // concurrent
481bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future
482bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future
483bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future
484bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
485bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                new int[] {id6, id4, id3, id2, id1}, PRIORITY_MIN);
486bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
487bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                maxNotifications);
488bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.validateNotificationsAndReset();
489bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
490bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increase time so some of the previously future ones change state.
491bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = createTimeInMillis(8, 15);
492bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future
493bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
494bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                new int[] {id8, id7, id6, id5, id4, id3, id2, id1}, PRIORITY_MIN);
495bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
496bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                maxNotifications);
49725b09db869f377b131052447f62ad02e2505cd87Michael Chan        ntm.validateNotificationsAndReset();
49825b09db869f377b131052447f62ad02e2505cd87Michael Chan    }
49921af116207d5728a312e534b898933bb07f96292Sara Ting
500bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
501bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testMultipleAlerts_max() {
502bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        MockSharedPreferences prefs = new MockSharedPreferences();
503bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
504bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
505bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Current time - 5:00
506bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = createTimeInMillis(5, 0);
507bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
508bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up future alerts.  The real query implementation sorts by descending start
509bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // time so simulate that here with our order of adds to AlertsTable.
510bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id9 = at.addAlertRow(9, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0),
511bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(10, 0), 0);
512bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id8 = at.addAlertRow(8, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0),
513bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(9, 0), 0);
514bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id7 = at.addAlertRow(7, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0),
515bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(8, 0), 0);
516bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
517bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up concurrent alerts (that started recently).
518bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id6 = at.addAlertRow(6, SCHEDULED, ACCEPTED, 0, createTimeInMillis(5, 0),
519bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(5, 40), 0);
520bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id5 = at.addAlertRow(5, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 55),
521bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(7, 30), 0);
522bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 50),
523bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(4, 50), 0);
524bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
525bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Set up past alerts.
526bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(3, 0),
527bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(4, 0), 0);
528bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(2, 0),
529bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(3, 0), 0);
530bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(1, 0),
531bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(2, 0), 0);
532bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
533bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Test when # alerts = max.
534bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int maxNotifications = 6;
535bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, maxNotifications);
536bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(6, id4, PRIORITY_HIGH); // concurrent
537bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(5, id5, PRIORITY_HIGH); // concurrent
538bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(4, id6, PRIORITY_HIGH); // concurrent
539bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future
540bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future
541bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future
542bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
543bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                new int[] {id3, id2, id1}, PRIORITY_MIN);
544bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
545bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                maxNotifications);
546bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.validateNotificationsAndReset();
547bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
548bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Test when # alerts > max.
549bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        maxNotifications = 4;
550bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm = new NotificationTestManager(at.mAlerts, maxNotifications);
551bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(4, id4, PRIORITY_HIGH); // concurrent
552bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(3, id5, PRIORITY_HIGH); // concurrent
553bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(2, id6, PRIORITY_HIGH); // concurrent
554bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(1, id7, PRIORITY_HIGH); // future
555bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
556bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                new int[] {id9, id8, id3, id2, id1}, PRIORITY_MIN);
557bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
558bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                maxNotifications);
559bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ntm.validateNotificationsAndReset();
560bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
56121af116207d5728a312e534b898933bb07f96292Sara Ting
562b5a2a61208857805cc053c6ac476d30100289279Sara Ting    /**
563b5a2a61208857805cc053c6ac476d30100289279Sara Ting     * Test that the SharedPreferences are only fetched once for each setting.
564b5a2a61208857805cc053c6ac476d30100289279Sara Ting     */
565b5a2a61208857805cc053c6ac476d30100289279Sara Ting    @SmallTest
566b5a2a61208857805cc053c6ac476d30100289279Sara Ting    public void testMultipleAlerts_sharedPreferences() {
567b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int maxNotifications = 10;
568b5a2a61208857805cc053c6ac476d30100289279Sara Ting        MockSharedPreferences prefs = new MockSharedPreferences(true /* strict mode */);
569b5a2a61208857805cc053c6ac476d30100289279Sara Ting        AlertsTable at = new AlertsTable();
570b5a2a61208857805cc053c6ac476d30100289279Sara Ting        NotificationTestManager ntm = new NotificationTestManager(at.mAlerts, maxNotifications);
571b5a2a61208857805cc053c6ac476d30100289279Sara Ting
572b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Current time - 5:00
573b5a2a61208857805cc053c6ac476d30100289279Sara Ting        long currentTime = createTimeInMillis(5, 0);
574b5a2a61208857805cc053c6ac476d30100289279Sara Ting
575b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Set up future alerts.  The real query implementation sorts by descending start
576b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // time so simulate that here with our order of adds to AlertsTable.
577b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id9 = at.addAlertRow(9, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0),
578b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(10, 0), 0);
579b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id8 = at.addAlertRow(8, SCHEDULED, ACCEPTED, 0, createTimeInMillis(8, 0),
580b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(9, 0), 0);
581b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id7 = at.addAlertRow(7, SCHEDULED, ACCEPTED, 0, createTimeInMillis(7, 0),
582b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(8, 0), 0);
583b5a2a61208857805cc053c6ac476d30100289279Sara Ting
584b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Set up concurrent alerts (that started recently).
585b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id6 = at.addAlertRow(6, SCHEDULED, ACCEPTED, 0, createTimeInMillis(5, 0),
586b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(5, 40), 0);
587b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id5 = at.addAlertRow(5, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 55),
588b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(7, 30), 0);
589b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id4 = at.addAlertRow(4, SCHEDULED, ACCEPTED, 0, createTimeInMillis(4, 50),
590b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(4, 50), 0);
591b5a2a61208857805cc053c6ac476d30100289279Sara Ting
592b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Set up past alerts.
593b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id3 = at.addAlertRow(3, SCHEDULED, ACCEPTED, 0, createTimeInMillis(3, 0),
594b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(4, 0), 0);
595b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id2 = at.addAlertRow(2, SCHEDULED, ACCEPTED, 0, createTimeInMillis(2, 0),
596b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(3, 0), 0);
597b5a2a61208857805cc053c6ac476d30100289279Sara Ting        int id1 = at.addAlertRow(1, SCHEDULED, ACCEPTED, 0, createTimeInMillis(1, 0),
598b5a2a61208857805cc053c6ac476d30100289279Sara Ting                createTimeInMillis(2, 0), 0);
599b5a2a61208857805cc053c6ac476d30100289279Sara Ting
600b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // Expected notifications.
601b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(6, id4, PRIORITY_HIGH); // concurrent
602b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(5, id5, PRIORITY_HIGH); // concurrent
603b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(4, id6, PRIORITY_HIGH); // concurrent
604b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(3, id7, PRIORITY_HIGH); // future
605b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(2, id8, PRIORITY_HIGH); // future
606b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(1, id9, PRIORITY_HIGH); // future
607b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.expectTestNotification(AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID,
608b5a2a61208857805cc053c6ac476d30100289279Sara Ting                new int[] {id3, id2, id1}, PRIORITY_MIN);
609b5a2a61208857805cc053c6ac476d30100289279Sara Ting
610b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // If this does not result in a failure (MockSharedPreferences fails for duplicate
611b5a2a61208857805cc053c6ac476d30100289279Sara Ting        // queries), then test passes.
612b5a2a61208857805cc053c6ac476d30100289279Sara Ting        AlertService.generateAlerts(mContext, ntm, prefs, at.getAlertCursor(), currentTime,
613b5a2a61208857805cc053c6ac476d30100289279Sara Ting                maxNotifications);
614b5a2a61208857805cc053c6ac476d30100289279Sara Ting        ntm.validateNotificationsAndReset();
615b5a2a61208857805cc053c6ac476d30100289279Sara Ting    }
616b5a2a61208857805cc053c6ac476d30100289279Sara Ting
61721af116207d5728a312e534b898933bb07f96292Sara Ting    private NotificationInfo createNotificationInfo(long eventId) {
61821af116207d5728a312e534b898933bb07f96292Sara Ting        return new NotificationInfo("eventName", "location", "description", 100L, 200L, eventId,
61921af116207d5728a312e534b898933bb07f96292Sara Ting                false, false);
62021af116207d5728a312e534b898933bb07f96292Sara Ting    }
62121af116207d5728a312e534b898933bb07f96292Sara Ting
622bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    private static long createTimeInMillis(int hour, int minute) {
623bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        return createTimeInMillis(0 /* second */, minute, hour, 1 /* day */, 1 /* month */,
624bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                2012 /* year */, Time.getCurrentTimezone());
625bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
626bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
627bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    private static long createTimeInMillis(int second, int minute, int hour, int monthDay,
628bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting            int month, int year, String timezone) {
629bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        Time t = new Time(timezone);
630bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        t.set(second, minute, hour, monthDay, month, year);
631bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        t.normalize(false);
632bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        return t.toMillis(false);
633bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
634bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
635bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
636bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testProcessQuery_skipDeclinedDismissed() {
637bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int declinedEventId = 1;
638bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int dismissedEventId = 2;
639bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int acceptedEventId = 3;
640bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long acceptedStartTime = createTimeInMillis(10, 0);
641bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long acceptedEndTime = createTimeInMillis(10, 30);
642bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
643bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
644bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(declinedEventId, SCHEDULED, DECLINED, 0, createTimeInMillis(9, 0),
645bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(10, 0), 0);
646bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(dismissedEventId, SCHEDULED, DISMISSED, 0, createTimeInMillis(9, 30),
647bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(11, 0), 0);
648bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(acceptedEventId, SCHEDULED, ACCEPTED, 1, acceptedStartTime, acceptedEndTime,
649bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                0);
650bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
651bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>();
652bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>();
653bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>();
654bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = createTimeInMillis(5, 0);
655bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
656bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
657bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
658bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
659bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
660bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
661bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(acceptedEventId, highPriority.get(0).eventId);
662bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(acceptedStartTime, highPriority.get(0).startMillis);
663bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(acceptedEndTime, highPriority.get(0).endMillis);
664bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertTrue(highPriority.get(0).allDay);
665bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
666bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
667bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
668bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testProcessQuery_newAlert() {
669bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int scheduledAlertEventId = 1;
670bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int firedAlertEventId = 2;
671bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
672bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
673bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(scheduledAlertEventId, SCHEDULED, ACCEPTED, 0, createTimeInMillis(9, 0),
674bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(10, 0), 0);
675bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(firedAlertEventId, FIRED, ACCEPTED, 0, createTimeInMillis(10, 0),
676bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                createTimeInMillis(10, 30), 0);
677bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
678bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>();
679bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>();
680bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>();
681bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = createTimeInMillis(5, 0);
682bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
683bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
684bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
685bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
686bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
687bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(2, highPriority.size());
688bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(scheduledAlertEventId, highPriority.get(0).eventId);
689bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertTrue("newAlert should be ON for scheduled alerts", highPriority.get(0).newAlert);
690bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(firedAlertEventId, highPriority.get(1).eventId);
691bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertFalse("newAlert should be OFF for fired alerts", highPriority.get(1).newAlert);
692bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
693bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
694bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
695bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testProcessQuery_recurringEvent() {
696bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int eventId = 1;
697bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long earlierStartTime = createTimeInMillis(10, 0);
698bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long laterStartTime = createTimeInMillis(11, 0);
699bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
700bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>();
701bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>();
702bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>();
703bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
704bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
705bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 0, laterStartTime,
706bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                laterStartTime + DateUtils.HOUR_IN_MILLIS, 0);
707bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(eventId, FIRED, ACCEPTED, 0, earlierStartTime,
708bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                earlierStartTime + DateUtils.HOUR_IN_MILLIS, 0);
709bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
710bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Both events in the future: the earliest one should be chosen.
711bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = earlierStartTime - DateUtils.DAY_IN_MILLIS * 5;
712bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
713bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
714bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
715bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
716bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
717bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with earlier start time expected", earlierStartTime,
718bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
719bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
720bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increment time just past the earlier event: the earlier one should be chosen.
721bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
722bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = earlierStartTime + DateUtils.MINUTE_IN_MILLIS * 10;
723bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
724bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
725bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
726bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
727bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
728bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with earlier start time expected", earlierStartTime,
729bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
730bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
731bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increment time to 15 min past the earlier event: the later one should be chosen.
732bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
733bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = earlierStartTime + DateUtils.MINUTE_IN_MILLIS * 15;
734bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
735bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
736bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
737bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
738bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
739bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with later start time expected", laterStartTime,
740bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
741bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
742bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Both events in the past: the later one should be chosen (in the low priority bucket).
743bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
744bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = laterStartTime + DateUtils.DAY_IN_MILLIS * 5;
745bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
746bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
747bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, highPriority.size());
748bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
749bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, lowPriority.size());
750bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with later start time expected", laterStartTime,
751bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                lowPriority.get(0).startMillis);
752bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
753bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
754bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    @SmallTest
755bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    public void testProcessQuery_recurringAllDayEvent() {
756bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        int eventId = 1;
757bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long day1 = createTimeInMillis(0, 0, 0, 1, 5, 2012, Time.TIMEZONE_UTC);
758bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long day2 = createTimeInMillis(0, 0, 0, 2, 5, 2012, Time.TIMEZONE_UTC);
759bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
760bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> highPriority = new ArrayList<NotificationInfo>();
761bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> mediumPriority = new ArrayList<NotificationInfo>();
762bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        ArrayList<NotificationInfo> lowPriority = new ArrayList<NotificationInfo>();
763bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
764bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertsTable at = new AlertsTable();
765bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 1, day2, day2 + DateUtils.HOUR_IN_MILLIS * 24,
766bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                0);
767bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        at.addAlertRow(eventId, SCHEDULED, ACCEPTED, 1, day1, day1 + DateUtils.HOUR_IN_MILLIS * 24,
768bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                0);
769bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
770bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Both events in the future: the earliest one should be chosen.
771bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        long currentTime = day1 - DateUtils.DAY_IN_MILLIS * 3;
772bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
773bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
774bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
775bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
776bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
777bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with earlier start time expected", day1,
778bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
779bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
780bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increment time just past the earlier event (to 12:10am).  The earlier one should
781bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // be chosen.
782bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
783bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = createTimeInMillis(0, 10, 0, 1, 5, 2012, Time.getCurrentTimezone());
784bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
785bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
786bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
787bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
788bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
789bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with earlier start time expected", day1,
790bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
791bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
792bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Increment time to 15 min past the earlier event: the later one should be chosen.
793bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
794bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = createTimeInMillis(0, 15, 0, 1, 5, 2012, Time.getCurrentTimezone());
795bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
796bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
797bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, lowPriority.size());
798bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
799bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, highPriority.size());
800bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with earlier start time expected", day2,
801bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                highPriority.get(0).startMillis);
802bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
803bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        // Both events in the past: the later one should be chosen (in the low priority bucket).
804bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        highPriority.clear();
805bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        currentTime = day2 + DateUtils.DAY_IN_MILLIS * 1;
806bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        AlertService.processQuery(at.getAlertCursor(), mContext, currentTime, highPriority,
807bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                mediumPriority, lowPriority);
808bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, highPriority.size());
809bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(0, mediumPriority.size());
810bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals(1, lowPriority.size());
811bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting        assertEquals("Recurring event with later start time expected", day2,
812bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting                lowPriority.get(0).startMillis);
813bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting    }
814bce26a2a19499790595e48ca36b43eb130e4a3fbSara Ting
81521af116207d5728a312e534b898933bb07f96292Sara Ting    @SmallTest
81621af116207d5728a312e534b898933bb07f96292Sara Ting    public void testRedistributeBuckets_withinLimits() throws Exception {
81721af116207d5728a312e534b898933bb07f96292Sara Ting        int maxNotifications = 3;
81821af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> threeItemList = new ArrayList<NotificationInfo>();
81921af116207d5728a312e534b898933bb07f96292Sara Ting        threeItemList.add(createNotificationInfo(5));
82021af116207d5728a312e534b898933bb07f96292Sara Ting        threeItemList.add(createNotificationInfo(4));
82121af116207d5728a312e534b898933bb07f96292Sara Ting        threeItemList.add(createNotificationInfo(3));
82221af116207d5728a312e534b898933bb07f96292Sara Ting
82321af116207d5728a312e534b898933bb07f96292Sara Ting        // Test when max notifications at high priority.
82421af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> high = threeItemList;
82521af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>();
82621af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>();
82721af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
82821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, high.size());
82921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, medium.size());
83021af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, low.size());
83121af116207d5728a312e534b898933bb07f96292Sara Ting
83221af116207d5728a312e534b898933bb07f96292Sara Ting        // Test when max notifications at medium priority.
83321af116207d5728a312e534b898933bb07f96292Sara Ting        high = new ArrayList<NotificationInfo>();
83421af116207d5728a312e534b898933bb07f96292Sara Ting        medium = threeItemList;
83521af116207d5728a312e534b898933bb07f96292Sara Ting        low = new ArrayList<NotificationInfo>();
83621af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
83721af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, high.size());
83821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, medium.size());
83921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, low.size());
84021af116207d5728a312e534b898933bb07f96292Sara Ting
84121af116207d5728a312e534b898933bb07f96292Sara Ting        // Test when max notifications at high and medium priority
84221af116207d5728a312e534b898933bb07f96292Sara Ting        high = new ArrayList<NotificationInfo>(threeItemList);
84321af116207d5728a312e534b898933bb07f96292Sara Ting        medium = new ArrayList<NotificationInfo>();
84421af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(high.remove(1));
84521af116207d5728a312e534b898933bb07f96292Sara Ting        low = new ArrayList<NotificationInfo>();
84621af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
84721af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, high.size());
84821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(1, medium.size());
84921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, low.size());
85021af116207d5728a312e534b898933bb07f96292Sara Ting    }
85121af116207d5728a312e534b898933bb07f96292Sara Ting
85221af116207d5728a312e534b898933bb07f96292Sara Ting    @SmallTest
85321af116207d5728a312e534b898933bb07f96292Sara Ting    public void testRedistributeBuckets_tooManyHighPriority() throws Exception {
85421af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>();
85521af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>();
85621af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>();
85721af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(5));
85821af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(4));
85921af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(3));
86021af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(2));
86121af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(1));
86221af116207d5728a312e534b898933bb07f96292Sara Ting
86321af116207d5728a312e534b898933bb07f96292Sara Ting        // Invoke the method under test.
86421af116207d5728a312e534b898933bb07f96292Sara Ting        int maxNotifications = 3;
86521af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
86621af116207d5728a312e534b898933bb07f96292Sara Ting
86721af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify some high priority were kicked out.
86821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, high.size());
86921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, high.get(0).eventId);
87021af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, high.get(1).eventId);
87121af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(1, high.get(2).eventId);
87221af116207d5728a312e534b898933bb07f96292Sara Ting
87321af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify medium priority untouched.
87421af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, medium.size());
87521af116207d5728a312e534b898933bb07f96292Sara Ting
87621af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify the extras went to low priority.
87721af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, low.size());
87821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(5, low.get(0).eventId);
87921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(4, low.get(1).eventId);
88021af116207d5728a312e534b898933bb07f96292Sara Ting    }
88121af116207d5728a312e534b898933bb07f96292Sara Ting
88221af116207d5728a312e534b898933bb07f96292Sara Ting    @SmallTest
88321af116207d5728a312e534b898933bb07f96292Sara Ting    public void testRedistributeBuckets_tooManyMediumPriority() throws Exception {
88421af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>();
88521af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>();
88621af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>();
88721af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(5));
88821af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(4));
88921af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(3));
89021af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(2));
89121af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(1));
89221af116207d5728a312e534b898933bb07f96292Sara Ting
89321af116207d5728a312e534b898933bb07f96292Sara Ting        // Invoke the method under test.
89421af116207d5728a312e534b898933bb07f96292Sara Ting        int maxNotifications = 3;
89521af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
89621af116207d5728a312e534b898933bb07f96292Sara Ting
89721af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify high priority untouched.
89821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, high.size());
89921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(5, high.get(0).eventId);
90021af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(4, high.get(1).eventId);
90121af116207d5728a312e534b898933bb07f96292Sara Ting
90221af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify some medium priority were kicked out (the ones near the end of the
90321af116207d5728a312e534b898933bb07f96292Sara Ting        // list).
90421af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(1, medium.size());
90521af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, medium.get(0).eventId);
90621af116207d5728a312e534b898933bb07f96292Sara Ting
90721af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify the extras went to low priority.
90821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, low.size());
90921af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, low.get(0).eventId);
91021af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(1, low.get(1).eventId);
91121af116207d5728a312e534b898933bb07f96292Sara Ting    }
91221af116207d5728a312e534b898933bb07f96292Sara Ting
91321af116207d5728a312e534b898933bb07f96292Sara Ting    @SmallTest
91421af116207d5728a312e534b898933bb07f96292Sara Ting    public void testRedistributeBuckets_tooManyHighMediumPriority() throws Exception {
91521af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> high = new ArrayList<NotificationInfo>();
91621af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> medium = new ArrayList<NotificationInfo>();
91721af116207d5728a312e534b898933bb07f96292Sara Ting        ArrayList<NotificationInfo> low = new ArrayList<NotificationInfo>();
91821af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(8));
91921af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(7));
92021af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(6));
92121af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(5));
92221af116207d5728a312e534b898933bb07f96292Sara Ting        high.add(createNotificationInfo(4));
92321af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(3));
92421af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(2));
92521af116207d5728a312e534b898933bb07f96292Sara Ting        medium.add(createNotificationInfo(1));
92621af116207d5728a312e534b898933bb07f96292Sara Ting
92721af116207d5728a312e534b898933bb07f96292Sara Ting        // Invoke the method under test.
92821af116207d5728a312e534b898933bb07f96292Sara Ting        int maxNotifications = 3;
92921af116207d5728a312e534b898933bb07f96292Sara Ting        AlertService.redistributeBuckets(high, medium, low, maxNotifications);
93021af116207d5728a312e534b898933bb07f96292Sara Ting
93121af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify high priority.
93221af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, high.size());
93321af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(6, high.get(0).eventId);
93421af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(5, high.get(1).eventId);
93521af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(4, high.get(2).eventId);
93621af116207d5728a312e534b898933bb07f96292Sara Ting
93721af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify some medium priority.
93821af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(0, medium.size());
93921af116207d5728a312e534b898933bb07f96292Sara Ting
94021af116207d5728a312e534b898933bb07f96292Sara Ting        // Verify low priority.
94121af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(5, low.size());
94221af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(8, low.get(0).eventId);
94321af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(7, low.get(1).eventId);
94421af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(3, low.get(2).eventId);
94521af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(2, low.get(3).eventId);
94621af116207d5728a312e534b898933bb07f96292Sara Ting        assertEquals(1, low.get(4).eventId);
94721af116207d5728a312e534b898933bb07f96292Sara Ting    }
94825b09db869f377b131052447f62ad02e2505cd87Michael Chan}
949