public void testBuildMessageTextFromEntityValues() {
    // Set up a test event
    String title = "Event Title";
    Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
    ContentValues entityValues = entity.getEntityValues();

    // Save this away; we'll use it a few times below
    Resources resources = mContext.getResources();
    Date date = new Date(entityValues.getAsLong(Events.DTSTART));
    String dateTimeString = DateFormat.getDateTimeInstance().format(date);

    // Get the text for this message
    StringBuilder sb = new StringBuilder();
    CalendarUtilities.buildMessageTextFromEntityValues(mContext, entityValues, sb);
    String text = sb.toString();
    // We'll just check the when and where
    assertTrue(text.contains(resources.getString(R.string.meeting_when, dateTimeString)));
    String location = entityValues.getAsString(Events.EVENT_LOCATION);
    assertTrue(text.contains(resources.getString(R.string.meeting_where, location)));

    // Make this event recurring
    entity.getEntityValues().put(Events.RRULE, "FREQ=WEEKLY;BYDAY=MO");
    sb = new StringBuilder();
    CalendarUtilities.buildMessageTextFromEntityValues(mContext, entityValues, sb);
    text = sb.toString();
    assertTrue(text.contains(resources.getString(R.string.meeting_recurring, dateTimeString)));
  }
 public void testRecurrenceUntilToEasUntil() {
   // Test full format
   assertEquals(
       "YYYYMMDDT000000Z", CalendarUtilities.recurrenceUntilToEasUntil("YYYYMMDDTHHMMSSZ"));
   // Test date only format
   assertEquals("YYYYMMDDT000000Z", CalendarUtilities.recurrenceUntilToEasUntil("YYYYMMDD"));
 }
  public void testGetLocalAllDayCalendarTime() {
    TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
    TimeZone localTimeZone = TimeZone.getTimeZone("GMT-0700");
    GregorianCalendar correctLocal = new GregorianCalendar(localTimeZone);
    correctLocal.set(2011, 2, 10, 0, 0, 0);
    long correctLocalTime = correctLocal.getTimeInMillis();

    GregorianCalendar utcCalendar = new GregorianCalendar(utcTimeZone);
    utcCalendar.set(2011, 2, 10, 12, 23, 34);
    long utcTimeMillis = utcCalendar.getTimeInMillis();
    long convertedLocalTime =
        CalendarUtilities.getLocalAllDayCalendarTime(utcTimeMillis, localTimeZone);
    // Milliseconds aren't zeroed out and may not be the same
    assertEquals(convertedLocalTime / 1000, correctLocalTime / 1000);

    localTimeZone = TimeZone.getTimeZone("GMT+0700");
    correctLocal = new GregorianCalendar(localTimeZone);
    correctLocal.set(2011, 2, 10, 0, 0, 0);
    correctLocalTime = correctLocal.getTimeInMillis();

    utcCalendar = new GregorianCalendar(utcTimeZone);
    utcCalendar.set(2011, 2, 10, 12, 23, 34);
    utcTimeMillis = utcCalendar.getTimeInMillis();
    convertedLocalTime = CalendarUtilities.getLocalAllDayCalendarTime(utcTimeMillis, localTimeZone);
    // Milliseconds aren't zeroed out and may not be the same
    assertEquals(convertedLocalTime / 1000, correctLocalTime / 1000);
  }
 public void testTokenFromRrule() {
   String rrule = "FREQ=DAILY;INTERVAL=1;BYDAY=WE,TH,SA;BYMONTHDAY=17";
   assertEquals("DAILY", CalendarUtilities.tokenFromRrule(rrule, "FREQ="));
   assertEquals("1", CalendarUtilities.tokenFromRrule(rrule, "INTERVAL="));
   assertEquals("17", CalendarUtilities.tokenFromRrule(rrule, "BYMONTHDAY="));
   assertEquals("WE,TH,SA", CalendarUtilities.tokenFromRrule(rrule, "BYDAY="));
   assertNull(CalendarUtilities.tokenFromRrule(rrule, "UNTIL="));
 }
 public void testGetIntegerValueAsBoolean() {
   ContentValues cv = new ContentValues();
   cv.put("A", 1);
   cv.put("B", 69);
   cv.put("C", 0);
   assertTrue(CalendarUtilities.getIntegerValueAsBoolean(cv, "A"));
   assertTrue(CalendarUtilities.getIntegerValueAsBoolean(cv, "B"));
   assertFalse(CalendarUtilities.getIntegerValueAsBoolean(cv, "C"));
   assertFalse(CalendarUtilities.getIntegerValueAsBoolean(cv, "D"));
 }
 public void testGenerateEasDayOfWeek() {
   String byDay = "TU,WE,SA";
   // TU = 4, WE = 8; SA = 64;
   assertEquals("76", CalendarUtilities.generateEasDayOfWeek(byDay));
   // MO = 2, TU = 4; WE = 8; TH = 16; FR = 32
   byDay = "MO,TU,WE,TH,FR";
   assertEquals("62", CalendarUtilities.generateEasDayOfWeek(byDay));
   // SU = 1
   byDay = "SU";
   assertEquals("1", CalendarUtilities.generateEasDayOfWeek(byDay));
 }
 public void testGetUidFromGlobalObjId() {
   // This is a "foreign" uid (from some vCalendar client)
   String globalObjId =
       "BAAAAIIA4AB0xbcQGoLgCAAAAAAAAAAAAAAAAAAAAAAAAAAAMQAAA"
           + "HZDYWwtVWlkAQAAADI3NjU1NmRkLTg1MzAtNGZiZS1iMzE0LThiM2JlYTYwMjE0OQA=";
   String uid = CalendarUtilities.getUidFromGlobalObjId(globalObjId);
   assertEquals(uid, "276556dd-8530-4fbe-b314-8b3bea602149");
   // This is a native EAS uid
   globalObjId = "BAAAAIIA4AB0xbcQGoLgCAAAAADACTu7KbPKAQAAAAAAAAAAEAAAAObgsG6HVt1Fmy+7GlLbGhY=";
   uid = CalendarUtilities.getUidFromGlobalObjId(globalObjId);
   assertEquals(
       uid,
       "040000008200E00074C5B7101A82E00800000000C0093BBB29B3CA"
           + "01000000000000000010000000E6E0B06E8756DD459B2FBB1A52DB1A16");
 }
 public void testSelfAttendeeStatusFromBusyStatus() {
   assertEquals(
       Attendees.ATTENDEE_STATUS_ACCEPTED,
       CalendarUtilities.attendeeStatusFromBusyStatus(CalendarUtilities.BUSY_STATUS_BUSY));
   assertEquals(
       Attendees.ATTENDEE_STATUS_TENTATIVE,
       CalendarUtilities.attendeeStatusFromBusyStatus(CalendarUtilities.BUSY_STATUS_TENTATIVE));
   assertEquals(
       Attendees.ATTENDEE_STATUS_NONE,
       CalendarUtilities.attendeeStatusFromBusyStatus(CalendarUtilities.BUSY_STATUS_FREE));
   assertEquals(
       Attendees.ATTENDEE_STATUS_NONE,
       CalendarUtilities.attendeeStatusFromBusyStatus(
           CalendarUtilities.BUSY_STATUS_OUT_OF_OFFICE));
 }
  private Entity setupTestEventEntity(String organizer, String attendee, String title) {
    // Create an Entity for an Event
    ContentValues entityValues = new ContentValues();
    Entity entity = new Entity(entityValues);

    // Set up values for the Event
    String location = "Meeting Location";

    // Fill in times, location, title, and organizer
    entityValues.put(
        "DTSTAMP",
        CalendarUtilities.convertEmailDateTimeToCalendarDateTime("2010-04-05T14:30:51Z"));
    entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis("2010-04-12T18:30:00Z"));
    entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis("2010-04-12T19:30:00Z"));
    entityValues.put(Events.EVENT_LOCATION, location);
    entityValues.put(Events.TITLE, title);
    entityValues.put(Events.ORGANIZER, organizer);
    entityValues.put(Events._SYNC_DATA, "31415926535");

    // Add the attendee
    ContentValues attendeeValues = new ContentValues();
    attendeeValues.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
    attendeeValues.put(Attendees.ATTENDEE_EMAIL, attendee);
    entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);

    // Add the organizer
    ContentValues organizerValues = new ContentValues();
    organizerValues.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
    organizerValues.put(Attendees.ATTENDEE_EMAIL, organizer);
    entity.addSubValue(Attendees.CONTENT_URI, organizerValues);
    return entity;
  }
 /**
  * Sanity test for time zone generation. Most important, make sure that we can run through all of
  * the time zones without generating an exception. Second, make sure that we're finding rules for
  * at least 90% of time zones that use daylight time (empirically, it's more like 95%). Log those
  * without rules.
  *
  * @throws IOException
  */
 public void testTimeZoneToVTimezone() throws IOException {
   SimpleIcsWriter writer = new SimpleIcsWriter();
   int rule = 0;
   int nodst = 0;
   int norule = 0;
   ArrayList<String> norulelist = new ArrayList<String>();
   for (String tzs : TimeZone.getAvailableIDs()) {
     TimeZone tz = TimeZone.getTimeZone(tzs);
     writer = new SimpleIcsWriter();
     CalendarUtilities.timeZoneToVTimezone(tz, writer);
     String vc = writer.toString();
     boolean hasRule = vc.indexOf("RRULE") > 0;
     if (hasRule) {
       rule++;
     } else if (tz.useDaylightTime()) {
       norule++;
       norulelist.add(tz.getID());
     } else {
       nodst++;
     }
   }
   assertTrue(norule < rule / 10);
   Log.d("TimeZoneGeneration", "Rule: " + rule + ", No DST: " + nodst + ", No rule: " + norule);
   for (String nr : norulelist) {
     Log.d("TimeZoneGeneration", "No rule: " + nr);
   }
 }
  public void testFindTransitionDate() {
    // We'll find some transitions and make sure that we're properly in or out of daylight time
    // on either side of the transition.
    // Use CST for testing (any other will do as well, as long as it has DST)
    TimeZone tz = TimeZone.getTimeZone("US/Central");
    // Get a calendar at January 1st of the current year
    GregorianCalendar calendar = new GregorianCalendar(tz);
    calendar.set(CalendarUtilities.sCurrentYear, Calendar.JANUARY, 1);
    // Get start and end times at start and end of year
    long startTime = calendar.getTimeInMillis();
    long endTime = startTime + (365 * CalendarUtilities.DAYS);
    // Find the first transition
    GregorianCalendar transitionCalendar =
        CalendarUtilities.findTransitionDate(tz, startTime, endTime, false);
    long transitionTime = transitionCalendar.getTimeInMillis();
    // Before should be in standard time; after in daylight time
    Date beforeDate = new Date(transitionTime - CalendarUtilities.HOURS);
    Date afterDate = new Date(transitionTime + CalendarUtilities.HOURS);
    assertFalse(tz.inDaylightTime(beforeDate));
    assertTrue(tz.inDaylightTime(afterDate));

    // Find the next one...
    transitionCalendar =
        CalendarUtilities.findTransitionDate(
            tz, transitionTime + CalendarUtilities.DAYS, endTime, true);
    transitionTime = transitionCalendar.getTimeInMillis();
    // This time, Before should be in daylight time; after in standard time
    beforeDate = new Date(transitionTime - CalendarUtilities.HOURS);
    afterDate = new Date(transitionTime + CalendarUtilities.HOURS);
    assertTrue(tz.inDaylightTime(beforeDate));
    assertFalse(tz.inDaylightTime(afterDate));

    // Captain Renault: What in heaven's name brought you to Casablanca?
    // Rick: My health. I came to Casablanca for the waters.
    // Also, they have no daylight savings time
    tz = TimeZone.getTimeZone("Africa/Casablanca");
    // Get a calendar at January 1st of the current year
    calendar = new GregorianCalendar(tz);
    calendar.set(CalendarUtilities.sCurrentYear, Calendar.JANUARY, 1);
    // Get start and end times at start and end of year
    startTime = calendar.getTimeInMillis();
    endTime = startTime + (365 * CalendarUtilities.DAYS);
    // Find the first transition
    transitionCalendar = CalendarUtilities.findTransitionDate(tz, startTime, endTime, false);
    // There had better not be one
    assertNull(transitionCalendar);
  }
 public void testBusyStatusFromSelfStatus() {
   assertEquals(
       CalendarUtilities.BUSY_STATUS_FREE,
       CalendarUtilities.busyStatusFromAttendeeStatus(Attendees.ATTENDEE_STATUS_DECLINED));
   assertEquals(
       CalendarUtilities.BUSY_STATUS_FREE,
       CalendarUtilities.busyStatusFromAttendeeStatus(Attendees.ATTENDEE_STATUS_NONE));
   assertEquals(
       CalendarUtilities.BUSY_STATUS_FREE,
       CalendarUtilities.busyStatusFromAttendeeStatus(Attendees.ATTENDEE_STATUS_INVITED));
   assertEquals(
       CalendarUtilities.BUSY_STATUS_TENTATIVE,
       CalendarUtilities.busyStatusFromAttendeeStatus(Attendees.ATTENDEE_STATUS_TENTATIVE));
   assertEquals(
       CalendarUtilities.BUSY_STATUS_BUSY,
       CalendarUtilities.busyStatusFromAttendeeStatus(Attendees.ATTENDEE_STATUS_ACCEPTED));
 }
  public void testGetSet() {
    byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};

    // First, check that getWord/Long are properly little endian
    assertEquals(0x0100, CalendarUtilities.getWord(bytes, 0));
    assertEquals(0x03020100, CalendarUtilities.getLong(bytes, 0));
    assertEquals(0x07060504, CalendarUtilities.getLong(bytes, 4));

    // Set some words and longs
    CalendarUtilities.setWord(bytes, 0, 0xDEAD);
    CalendarUtilities.setLong(bytes, 2, 0xBEEFBEEF);
    CalendarUtilities.setWord(bytes, 6, 0xCEDE);

    // Retrieve them
    assertEquals(0xDEAD, CalendarUtilities.getWord(bytes, 0));
    assertEquals(0xBEEFBEEF, CalendarUtilities.getLong(bytes, 2));
    assertEquals(0xCEDE, CalendarUtilities.getWord(bytes, 6));
  }
  public void testCreateMessageForEntity_Reply() {
    // Set up the "event"
    String title = "Discuss Unit Tests";
    Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);

    // Create a dummy account for the attendee
    Account account = new Account();
    account.mEmailAddress = ATTENDEE;

    // The uid is required, but can be anything
    String uid = "31415926535";

    // Create the outgoing message
    Message msg =
        CalendarUtilities.createMessageForEntity(
            mContext, entity, Message.FLAG_OUTGOING_MEETING_ACCEPT, uid, account);

    // First, we should have a message
    assertNotNull(msg);

    // Now check some of the fields of the message
    assertEquals(Address.pack(new Address[] {new Address(ORGANIZER)}), msg.mTo);
    Resources resources = getContext().getResources();
    String accept = resources.getString(R.string.meeting_accepted, title);
    assertEquals(accept, msg.mSubject);
    assertNotNull(msg.mText);
    assertTrue(msg.mText.contains(resources.getString(R.string.meeting_where, "")));

    // And make sure we have an attachment
    assertNotNull(msg.mAttachments);
    assertEquals(1, msg.mAttachments.size());
    Attachment att = msg.mAttachments.get(0);
    // And that the attachment has the correct elements
    assertEquals("invite.ics", att.mFileName);
    assertEquals(
        Attachment.FLAG_ICS_ALTERNATIVE_PART, att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
    assertEquals("text/calendar; method=REPLY", att.mMimeType);
    assertNotNull(att.mContentBytes);
    assertEquals(att.mSize, att.mContentBytes.length);

    // TODO Check the contents of the attachment using an iCalendar parser
  }
 public void testParseTimeZoneEndToEnd() {
   TimeZone tz = CalendarUtilities.tziStringToTimeZone(AMERICA_DAWSON_TIME);
   assertEquals("America/Dawson", tz.getID());
   tz = CalendarUtilities.tziStringToTimeZone(ASIA_CALCUTTA_TIME);
   assertEquals("Asia/Calcutta", tz.getID());
   tz = CalendarUtilities.tziStringToTimeZone(AUSTRALIA_ACT_TIME);
   assertEquals("Australia/ACT", tz.getID());
   tz = CalendarUtilities.tziStringToTimeZone(EUROPE_MOSCOW_TIME);
   assertEquals("Europe/Moscow", tz.getID());
   tz = CalendarUtilities.tziStringToTimeZone(GMT_UNKNOWN_DAYLIGHT_TIME);
   int bias = tz.getOffset(System.currentTimeMillis());
   assertEquals(0, bias);
   // Make sure non-DST TZ's work properly
   tz = CalendarUtilities.tziStringToTimeZone(ARIZONA_TIME);
   assertEquals("America/Phoenix", tz.getID());
 }
 public void testRruleFromRecurrence() {
   // Every Monday for 2 weeks
   String rrule =
       CalendarUtilities.rruleFromRecurrence(
           1 /*Weekly*/, 2 /*Occurrences*/, 1 /*Interval*/, 2 /*Monday*/, 0, 0, 0, null);
   assertEquals("FREQ=WEEKLY;INTERVAL=1;COUNT=2;BYDAY=MO", rrule);
   // Every Tuesday and Friday
   rrule =
       CalendarUtilities.rruleFromRecurrence(
           1 /*Weekly*/, 0 /*Occurrences*/, 0 /*Interval*/, 36 /*Tue&Fri*/, 0, 0, 0, null);
   assertEquals("FREQ=WEEKLY;BYDAY=TU,FR", rrule);
   // The last Saturday of the month
   rrule =
       CalendarUtilities.rruleFromRecurrence(
           3 /*Monthly/DayofWeek*/, 0, 0, 64 /*Sat*/, 0, 5 /*Last*/, 0, null);
   assertEquals("FREQ=MONTHLY;BYDAY=-1SA", rrule);
   // The third Wednesday and Thursday of the month
   rrule =
       CalendarUtilities.rruleFromRecurrence(
           3 /*Monthly/DayofWeek*/, 0, 0, 24 /*Wed&Thu*/, 0, 3 /*3rd*/, 0, null);
   assertEquals("FREQ=MONTHLY;BYDAY=3WE,3TH", rrule);
   // The 14th of the every month
   rrule =
       CalendarUtilities.rruleFromRecurrence(2 /*Monthly/Date*/, 0, 0, 0, 14 /*14th*/, 0, 0, null);
   assertEquals("FREQ=MONTHLY;BYMONTHDAY=14", rrule);
   // Every 31st of October
   rrule =
       CalendarUtilities.rruleFromRecurrence(
           5 /*Yearly/Date*/, 0, 0, 0, 31 /*31st*/, 0, 10 /*October*/, null);
   assertEquals("FREQ=YEARLY;BYMONTHDAY=31;BYMONTH=10", rrule);
   // The first Tuesday of June
   rrule =
       CalendarUtilities.rruleFromRecurrence(
           6 /*Yearly/Month/DayOfWeek*/, 0, 0, 4 /*Tue*/, 0, 1 /*1st*/, 6 /*June*/, null);
   assertEquals("FREQ=YEARLY;BYDAY=1TU;BYMONTH=6", rrule);
 }
  public void testCreateMessageForEntity_Recurring() throws IOException {
    // Set up the "event"
    String title = "Discuss Unit Tests";
    Entity entity = setupTestEventEntity(ORGANIZER, ATTENDEE, title);
    // Set up a RRULE for this event
    entity.getEntityValues().put(Events.RRULE, "FREQ=DAILY");

    // Create a dummy account for the attendee
    Account account = new Account();
    account.mEmailAddress = ORGANIZER;

    // The uid is required, but can be anything
    String uid = "31415926535";

    // Create the outgoing message
    Message msg =
        CalendarUtilities.createMessageForEntity(
            mContext, entity, Message.FLAG_OUTGOING_MEETING_INVITE, uid, account);

    // First, we should have a message
    assertNotNull(msg);

    // Now check some of the fields of the message
    assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
    assertEquals(title, msg.mSubject);

    // And make sure we have an attachment
    assertNotNull(msg.mAttachments);
    assertEquals(1, msg.mAttachments.size());
    Attachment att = msg.mAttachments.get(0);
    // And that the attachment has the correct elements
    assertEquals("invite.ics", att.mFileName);
    assertEquals(
        Attachment.FLAG_ICS_ALTERNATIVE_PART, att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
    assertEquals("text/calendar; method=REQUEST", att.mMimeType);
    assertNotNull(att.mContentBytes);
    assertEquals(att.mSize, att.mContentBytes.length);

    // We'll check the contents of the ics file here
    BlockHash vcalendar = parseIcsContent(att.mContentBytes);
    assertNotNull(vcalendar);

    // We should have a VCALENDAR with a REQUEST method
    assertEquals("VCALENDAR", vcalendar.name);
    assertEquals("REQUEST", vcalendar.get("METHOD"));

    // We should have two blocks under VCALENDAR (VTIMEZONE and VEVENT)
    assertEquals(2, vcalendar.blocks.size());

    // This is the time zone that should be used
    TimeZone timeZone = TimeZone.getDefault();

    BlockHash vtimezone = vcalendar.blocks.get(0);
    // It should be a VTIMEZONE for timeZone
    assertEquals("VTIMEZONE", vtimezone.name);
    assertEquals(timeZone.getID(), vtimezone.get("TZID"));

    BlockHash vevent = vcalendar.blocks.get(1);
    // It's a VEVENT with the following fields
    assertEquals("VEVENT", vevent.name);
    assertEquals("Meeting Location", vevent.get("LOCATION"));
    assertEquals("0", vevent.get("SEQUENCE"));
    assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
    assertEquals(uid, vevent.get("UID"));
    assertEquals(
        "MAILTO:" + ATTENDEE,
        vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE"));

    // We should have DTSTART/DTEND with time zone
    assertNotNull(vevent.get("DTSTART;TZID=" + timeZone.getID()));
    assertNotNull(vevent.get("DTEND;TZID=" + timeZone.getID()));
    assertNull(vevent.get("DTSTART"));
    assertNull(vevent.get("DTEND"));
    assertNull(vevent.get("DTSTART;VALUE=DATE"));
    assertNull(vevent.get("DTEND;VALUE=DATE"));
    // This shouldn't exist for this event
    assertNull(vevent.get("X-MICROSOFT-CDO-ALLDAYEVENT"));
  }
  public void testCreateMessageForEntity_Exception_Cancel() throws IOException {
    // Set up the "exception"...
    String title = "Discuss Unit Tests";
    Entity entity = setupTestExceptionEntity(ORGANIZER, ATTENDEE, title);

    ContentValues entityValues = entity.getEntityValues();
    // Mark the Exception as dirty
    entityValues.put(Events._SYNC_DIRTY, 1);
    // And mark it canceled
    entityValues.put(Events.STATUS, Events.STATUS_CANCELED);

    // Create a dummy account for the attendee
    Account account = new Account();
    account.mEmailAddress = ORGANIZER;

    // The uid is required, but can be anything
    String uid = "31415926535";

    // Create the outgoing message
    Message msg =
        CalendarUtilities.createMessageForEntity(
            mContext, entity, Message.FLAG_OUTGOING_MEETING_CANCEL, uid, account);

    // First, we should have a message
    assertNotNull(msg);

    // Now check some of the fields of the message
    assertEquals(Address.pack(new Address[] {new Address(ATTENDEE)}), msg.mTo);
    String cancel = getContext().getResources().getString(R.string.meeting_canceled, title);
    assertEquals(cancel, msg.mSubject);

    // And make sure we have an attachment
    assertNotNull(msg.mAttachments);
    assertEquals(1, msg.mAttachments.size());
    Attachment att = msg.mAttachments.get(0);
    // And that the attachment has the correct elements
    assertEquals("invite.ics", att.mFileName);
    assertEquals(
        Attachment.FLAG_ICS_ALTERNATIVE_PART, att.mFlags & Attachment.FLAG_ICS_ALTERNATIVE_PART);
    assertEquals("text/calendar; method=CANCEL", att.mMimeType);
    assertNotNull(att.mContentBytes);

    // We'll check the contents of the ics file here
    BlockHash vcalendar = parseIcsContent(att.mContentBytes);
    assertNotNull(vcalendar);

    // We should have a VCALENDAR with a CANCEL method
    assertEquals("VCALENDAR", vcalendar.name);
    assertEquals("CANCEL", vcalendar.get("METHOD"));

    // This is the time zone that should be used
    TimeZone timeZone = TimeZone.getDefault();

    // We should have two blocks under VCALENDAR (VTIMEZONE and VEVENT)
    assertEquals(2, vcalendar.blocks.size());

    BlockHash vtimezone = vcalendar.blocks.get(0);
    // It should be a VTIMEZONE for timeZone
    assertEquals("VTIMEZONE", vtimezone.name);
    assertEquals(timeZone.getID(), vtimezone.get("TZID"));

    BlockHash vevent = vcalendar.blocks.get(1);
    // It's a VEVENT with the following fields
    assertEquals("VEVENT", vevent.name);
    assertEquals("Meeting Location", vevent.get("LOCATION"));
    assertEquals("0", vevent.get("SEQUENCE"));
    assertEquals("Discuss Unit Tests", vevent.get("SUMMARY"));
    assertEquals(uid, vevent.get("UID"));
    assertEquals("MAILTO:" + ATTENDEE, vevent.get("ATTENDEE;ROLE=REQ-PARTICIPANT"));
    long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
    assertNotSame(0, originalTime);
    // For an exception, RECURRENCE-ID is critical
    assertEquals(
        CalendarUtilities.millisToEasDateTime(originalTime, timeZone, true /*withTime*/),
        vevent.get("RECURRENCE-ID" + ";TZID=" + timeZone.getID()));
  }
 public void testUtcOffsetString() {
   assertEquals(CalendarUtilities.utcOffsetString(540), "+0900");
   assertEquals(CalendarUtilities.utcOffsetString(-480), "-0800");
   assertEquals(CalendarUtilities.utcOffsetString(0), "+0000");
 }