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