1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.calendar; 18 19 import android.content.res.Configuration; 20 import android.database.MatrixCursor; 21 import android.provider.CalendarContract.CalendarCache; 22 import android.test.mock.MockResources; 23 import android.text.format.Time; 24 import android.util.DisplayMetrics; 25 26 import androidx.test.filters.SmallTest; 27 28 import com.android.calendar.CalendarUtils.TimeZoneUtils; 29 30 import junit.framework.TestCase; 31 32 import java.util.HashMap; 33 import java.util.Locale; 34 35 /** 36 * Test class for verifying helper functions in Calendar's Utils 37 * 38 * You can run these tests with the following command: 39 * "adb shell am instrument -w -e class com.android.calendar.UtilsTests 40 * com.android.calendar.tests/android.test.InstrumentationTestRunner" 41 */ 42 public class UtilsTests extends TestCase { 43 HashMap<String, Boolean> mIsDuplicateName; 44 HashMap<String, Boolean> mIsDuplicateNameExpected; 45 MatrixCursor mDuplicateNameCursor; 46 private DbTestUtils dbUtils; 47 private final TimeZoneUtils timezoneUtils = new TimeZoneUtils(Utils.SHARED_PREFS_NAME); 48 49 private static final int NAME_COLUMN = 0; 50 private static final String[] DUPLICATE_NAME_COLUMNS = new String[] { "name" }; 51 private static final String[][] DUPLICATE_NAMES = new String[][] { 52 {"Pepper Pots"}, 53 {"Green Goblin"}, 54 {"Pepper Pots"}, 55 {"Peter Parker"}, 56 {"Silver Surfer"}, 57 {"John Jameson"}, 58 {"John Jameson"}, 59 {"Pepper Pots"} 60 }; 61 // First date is Thursday, Jan 1st, 1970. 62 private static final int[] JULIAN_DAYS = {2440588, 2440589, 2440590, 2440591, 2440592, 2440593, 63 2440594, 2440595, 2440596, 2440597, 2440598, 2440599, 2440600, 2440601 64 }; 65 private static final int[] EXPECTED_WEEK_MONDAY_START = { 66 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2 }; 67 private static final int[] EXPECTED_WEEK_SUNDAY_START = { 68 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 }; 69 private static final int[] EXPECTED_WEEK_SATURDAY_START = { 70 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; 71 private static final int[] WEEKS_FOR_JULIAN_MONDAYS = {1, 2}; 72 private static final int[] EXPECTED_JULIAN_MONDAYS = {2440592, 2440599}; 73 74 private static final int NOW_MONTH = 3; // April 75 private static final int NOW_DAY = 10; 76 private static final int NOW_YEAR = 2012; 77 private static final long NOW_TIME = createTimeInMillis(5, 5, 5, NOW_DAY, NOW_MONTH, NOW_YEAR); 78 private static final String DEFAULT_TIMEZONE = Time.getCurrentTimezone(); 79 80 /** 81 * Mock resources. Add translation strings for test here. 82 */ 83 private static class ResourcesForTest extends MockResources { 84 @Override getString(int id)85 public String getString(int id) { 86 if (id == R.string.today) { 87 return "Today"; 88 } 89 if (id == R.string.tomorrow) { 90 return "Tomorrow"; 91 } 92 throw new IllegalArgumentException("unexpected resource ID: " + id); 93 } 94 95 @Override getString(int id, Object... formatArgs)96 public String getString(int id, Object... formatArgs) { 97 if (id == R.string.today_at_time_fmt) { 98 return String.format("Today at %s", formatArgs); 99 } 100 if (id == R.string.tomorrow_at_time_fmt) { 101 return String.format("Tomorrow at %s", formatArgs); 102 } 103 if (id == R.string.date_time_fmt) { 104 return String.format("%s, %s", formatArgs); 105 } 106 throw new IllegalArgumentException("unexpected resource ID: " + id); 107 } 108 109 @Override getConfiguration()110 public Configuration getConfiguration() { 111 Configuration config = new Configuration(); 112 config.locale = Locale.getDefault(); 113 return config; 114 } 115 116 @Override getDisplayMetrics()117 public DisplayMetrics getDisplayMetrics(){ 118 DisplayMetrics metrics = new DisplayMetrics(); 119 metrics.density = 2.0f; 120 return metrics; 121 } 122 } 123 createTimeInMillis(int second, int minute, int hour, int monthDay, int month, int year)124 private static long createTimeInMillis(int second, int minute, int hour, int monthDay, 125 int month, int year) { 126 return createTimeInMillis(second, minute, hour, monthDay, month, year, 127 Time.getCurrentTimezone()); 128 } 129 createTimeInMillis(int second, int minute, int hour, int monthDay, int month, int year, String timezone)130 private static long createTimeInMillis(int second, int minute, int hour, int monthDay, 131 int month, int year, String timezone) { 132 Time t = new Time(timezone); 133 t.set(second, minute, hour, monthDay, month, year); 134 t.normalize(false); 135 return t.toMillis(false); 136 } 137 setTimezone(String tz)138 private void setTimezone(String tz) { 139 timezoneUtils.setTimeZone(dbUtils.getContext(), tz); 140 } 141 142 @Override setUp()143 public void setUp() { 144 mIsDuplicateName = new HashMap<String, Boolean> (); 145 mDuplicateNameCursor = new MatrixCursor(DUPLICATE_NAME_COLUMNS); 146 for (int i = 0; i < DUPLICATE_NAMES.length; i++) { 147 mDuplicateNameCursor.addRow(DUPLICATE_NAMES[i]); 148 } 149 150 mIsDuplicateNameExpected = new HashMap<String, Boolean> (); 151 mIsDuplicateNameExpected.put("Pepper Pots", true); 152 mIsDuplicateNameExpected.put("Green Goblin", false); 153 mIsDuplicateNameExpected.put("Peter Parker", false); 154 mIsDuplicateNameExpected.put("Silver Surfer", false); 155 mIsDuplicateNameExpected.put("John Jameson", true); 156 157 // Set up fake db. 158 dbUtils = new DbTestUtils(new ResourcesForTest()); 159 dbUtils.getContentResolver().addProvider("settings", dbUtils.getContentProvider()); 160 dbUtils.getContentResolver().addProvider(CalendarCache.URI.getAuthority(), 161 dbUtils.getContentProvider()); 162 163 setTimezone(DEFAULT_TIMEZONE); 164 } 165 166 @Override tearDown()167 public void tearDown() { 168 mDuplicateNameCursor.close(); 169 170 // Must reset the timezone here, because even though the fake provider will be 171 // recreated/cleared, TimeZoneUtils statically holds on to a cached value. 172 setTimezone(Time.getCurrentTimezone()); 173 } 174 175 @SmallTest testGetWeeksSinceEpochFromJulianDay()176 public void testGetWeeksSinceEpochFromJulianDay() { 177 for (int i = 0; i < JULIAN_DAYS.length; i++) { 178 assertEquals(EXPECTED_WEEK_MONDAY_START[i], 179 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.MONDAY)); 180 assertEquals(EXPECTED_WEEK_SUNDAY_START[i], 181 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.SUNDAY)); 182 assertEquals(EXPECTED_WEEK_SATURDAY_START[i], 183 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.SATURDAY)); 184 } 185 } 186 187 @SmallTest testGetJulianMondayFromWeeksSinceEpoch()188 public void testGetJulianMondayFromWeeksSinceEpoch() { 189 for (int i = 0; i < WEEKS_FOR_JULIAN_MONDAYS.length; i++) { 190 assertEquals(EXPECTED_JULIAN_MONDAYS[i], 191 Utils.getJulianMondayFromWeeksSinceEpoch(WEEKS_FOR_JULIAN_MONDAYS[i])); 192 } 193 } 194 195 // Helper function to create test events for BusyBits testing buildTestEvent(int startTime, int endTime, boolean allDay, int startDay, int endDay)196 Event buildTestEvent(int startTime, int endTime, boolean allDay, int startDay, int endDay) { 197 Event e = new Event(); 198 e.startTime = startTime; 199 e.endTime = endTime; 200 e.allDay = allDay; 201 e.startDay = startDay; 202 e.endDay = endDay; 203 e.startMillis = e.startDay * 1000L * 3600L * 24L + e.startTime * 60L * 1000L; 204 e.endMillis = e.endDay * 1000L * 3600L * 24L + e.endTime * 60L * 1000L; 205 return e; 206 } 207 208 @SmallTest testGetDisplayedDatetime_differentYear()209 public void testGetDisplayedDatetime_differentYear() { 210 // 4/12/2000 5pm - 4/12/2000 6pm 211 long start = createTimeInMillis(0, 0, 17, 12, 3, 2000); 212 long end = createTimeInMillis(0, 0, 18, 12, 3, 2000); 213 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 214 false, dbUtils.getContext()); 215 assertEquals("Wednesday, April 12, 2000, 5:00 \u2013 6:00 PM", result); 216 217 // 12/31/2012 5pm - 1/1/2013 6pm 218 start = createTimeInMillis(0, 0, 17, 31, 11, 2012); 219 end = createTimeInMillis(0, 0, 18, 1, 0, 2013); 220 result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 221 false, dbUtils.getContext()); 222 assertEquals("Mon, Dec 31, 2012, 5:00 PM – Tue, Jan 1, 2013, 6:00 PM", result); 223 } 224 225 @SmallTest testGetDisplayedDatetime_sameYear()226 public void testGetDisplayedDatetime_sameYear() { 227 // 4/12/2012 5pm - 4/12/2012 6pm 228 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012); 229 long end = createTimeInMillis(0, 0, 18, 12, 3, 2012); 230 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 231 false, dbUtils.getContext()); 232 assertEquals("Thursday, April 12, 2012, 5:00 \u2013 6:00 PM", result); 233 } 234 235 @SmallTest testGetDisplayedDatetime_today()236 public void testGetDisplayedDatetime_today() { 237 // 4/10/2012 5pm - 4/10/2012 6pm 238 long start = createTimeInMillis(0, 0, 17, NOW_DAY, NOW_MONTH, NOW_YEAR); 239 long end = createTimeInMillis(0, 0, 18, NOW_DAY, NOW_MONTH, NOW_YEAR); 240 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 241 false, dbUtils.getContext()); 242 assertEquals("Today at 5:00 \u2013 6:00 PM", result); 243 } 244 245 @SmallTest testGetDisplayedDatetime_todayMidnight()246 public void testGetDisplayedDatetime_todayMidnight() { 247 // 4/10/2012 5pm - 4/11/2012 12am 248 long start = createTimeInMillis(0, 0, 17, NOW_DAY, NOW_MONTH, NOW_YEAR); 249 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 250 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 251 false, dbUtils.getContext()); 252 assertEquals("Today at 5:00 PM \u2013 12:00 AM", result); 253 } 254 255 @SmallTest testGetDisplayedDatetime_tomorrow()256 public void testGetDisplayedDatetime_tomorrow() { 257 // 4/11/2012 12:01AM - 4/11/2012 11:59pm 258 long start = createTimeInMillis(0, 1, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 259 long end = createTimeInMillis(0, 59, 23, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 260 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 261 false, dbUtils.getContext()); 262 assertEquals("Tomorrow at 12:01 AM \u2013 11:59 PM", result); 263 } 264 265 @SmallTest testGetDisplayedDatetime_yesterday()266 public void testGetDisplayedDatetime_yesterday() { 267 // 4/9/2012 5pm - 4/9/2012 6pm 268 long start = createTimeInMillis(0, 0, 17, 9, 3, 2012); 269 long end = createTimeInMillis(0, 0, 18, 9, 3, 2012); 270 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 271 false, dbUtils.getContext()); 272 assertEquals("Monday, April 9, 2012, 5:00 \u2013 6:00 PM", result); 273 } 274 275 @SmallTest testGetDisplayedDatetime_multiDay()276 public void testGetDisplayedDatetime_multiDay() { 277 // 4/10/2012 12:01AM - 4/11/2012 12:01AM 278 long start = createTimeInMillis(0, 1, 0, NOW_DAY, NOW_MONTH, NOW_YEAR); 279 long end = createTimeInMillis(0, 1, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 280 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 281 false, dbUtils.getContext()); 282 assertEquals("Tue, Apr 10, 2012, 12:01 AM \u2013 Wed, Apr 11, 2012, 12:01 AM", result); 283 } 284 285 @SmallTest testGetDisplayedDatetime_allDay()286 public void testGetDisplayedDatetime_allDay() { 287 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 288 long start = createTimeInMillis(0, 0, 0, 2, 3, NOW_YEAR, Time.TIMEZONE_UTC); 289 long end = createTimeInMillis(0, 0, 0, 3, 3, NOW_YEAR, Time.TIMEZONE_UTC); 290 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 291 true, dbUtils.getContext()); 292 assertEquals("Monday, April 2, 2012", result); 293 } 294 295 @SmallTest testGetDisplayedDatetime_allDayToday()296 public void testGetDisplayedDatetime_allDayToday() { 297 // 4/10/2012 12:00AM - 4/11/2012 12:00AM 298 long start = createTimeInMillis(0, 0, 0, NOW_DAY, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 299 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 300 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 301 true, dbUtils.getContext()); 302 assertEquals("Today", result); 303 } 304 305 @SmallTest testGetDisplayedDatetime_allDayMultiday()306 public void testGetDisplayedDatetime_allDayMultiday() { 307 // 4/10/2012 12:00AM - 4/13/2012 12:00AM 308 long start = createTimeInMillis(0, 0, 0, NOW_DAY, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 309 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 3, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 310 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 311 true, dbUtils.getContext()); 312 assertEquals("Tuesday, April 10 \u2013 Thursday, April 12, 2012", result); 313 } 314 315 @SmallTest testGetDisplayedDatetime_differentTimezone()316 public void testGetDisplayedDatetime_differentTimezone() { 317 String localTz = "America/New_York"; 318 String eventTz = "America/Los_Angeles"; 319 setTimezone(localTz); 320 321 // 4/12/2012 5pm - 4/12/2012 6pm (Pacific) 322 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, eventTz); 323 long end = createTimeInMillis(0, 0, 18, 12, 3, 2012, eventTz); 324 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, false, 325 dbUtils.getContext()); 326 assertEquals("Thursday, April 12, 2012, 8:00 \u2013 9:00 PM", result); 327 } 328 329 @SmallTest testGetDisplayedDatetime_allDayDiffTimezone()330 public void testGetDisplayedDatetime_allDayDiffTimezone() { 331 String localTz = "America/New_York"; 332 setTimezone(localTz); 333 334 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 335 long start = createTimeInMillis(0, 0, 0, 2, 3, NOW_YEAR, Time.TIMEZONE_UTC); 336 long end = createTimeInMillis(0, 0, 0, 3, 3, NOW_YEAR, Time.TIMEZONE_UTC); 337 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, true, 338 dbUtils.getContext()); 339 assertEquals("Monday, April 2, 2012", result); 340 } 341 342 @SmallTest testGetDisplayedDatetime_allDayTomorrowDiffTimezone()343 public void testGetDisplayedDatetime_allDayTomorrowDiffTimezone() { 344 String localTz = "America/New_York"; 345 setTimezone(localTz); 346 347 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 348 long start = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR, 349 Time.TIMEZONE_UTC); 350 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 2, NOW_MONTH, NOW_YEAR, 351 Time.TIMEZONE_UTC); 352 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, true, 353 dbUtils.getContext()); 354 assertEquals("Tomorrow", result); 355 } 356 357 // TODO: add tests for army time. 358 359 @SmallTest testGetDisplayedTimezone_sameTimezone()360 public void testGetDisplayedTimezone_sameTimezone() { 361 String localTz = "America/New_York"; 362 setTimezone(localTz); 363 364 // 4/12/2012 5pm 365 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, localTz); 366 assertNull(Utils.getDisplayedTimezone(start, localTz, localTz)); 367 } 368 369 @SmallTest testGetDisplayedTimezone_differentTimezone()370 public void testGetDisplayedTimezone_differentTimezone() { 371 String localTz = "America/New_York"; 372 String eventTz = "America/Los_Angeles"; 373 setTimezone(localTz); 374 375 // 1/12/2012 5pm (not daylight savings) 376 long start = createTimeInMillis(0, 0, 17, 12, 0, 2012, eventTz); 377 assertEquals("EST", Utils.getDisplayedTimezone(start, localTz, eventTz)); 378 } 379 380 @SmallTest testGetDisplayedTimezone_differentTimezoneDst()381 public void testGetDisplayedTimezone_differentTimezoneDst() { 382 String localTz = "America/New_York"; 383 String eventTz = "America/Los_Angeles"; 384 setTimezone(localTz); 385 386 // 4/12/2012 5pm (daylight savings) 387 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, eventTz); 388 assertEquals("EDT", Utils.getDisplayedTimezone(start, localTz, eventTz)); 389 } 390 } 391