New iTIP Processor Interface

This is based off of the iTIPResponder Patch in bug 334685

This will be the proposed interface into the iTIP Processor that will handle all forms of iTIP action, from replying to an iTIP REQUEST to Rescheduling an invitation (eventually).

The interface is simple. An iTIP invitation is encapsulated as an ItipItem. An ItipItem is one or more iCALENDAR (RFC 2445) objects that are the same type with the same iTIP METHOD (such as PUBLISH). We also use the ItipItem to designate the user's preference for handling the item. The user can specify whether or not to allow automatic, preference based handling of an ItipItem. This would occur if the user had set up a preference setting to "Always Add all Publish Events to Calendar X". Or, the user can direct what method they would like to respond to an iTIP invitation. For example, the user may wish to decline an invitation to a meeting. This information is encapsulated into the ItipItem before it is sent to the ItipProcessorService object.

If the ItipItem is not fully specified when it is received by the ItipProcessorService, the ItipProcessorService will use the user's iTIP Preference settings to act on the ItipItem appropriately.

To this end, there are just two interfaces needed into the ItipProcessorService.

  • getItipPreference
  • process

The interface would also define preference constants to refer to specific iTIP preferences (the iTIP Preferences would be repeated for each combination of Method and VComponent (VEVENT, VTODO, etc)):

  • const unsigned long targetCalendar; // Default calendar to add/update/delete to/from. lilmatt: should this be AUTF8String instead to handle UIDs?
  • const unsigned long defaultResponseMethod; // Default response method for this particular iTIP method and VComponent combination
  • const unsigned long isHandledAutomatically; // Whether or not the ItipProcessorService handles this combination of iTIP method and VComponent combination automatically. lilmatt: should this be a boolean rather than a long?
  • TODO: Do we need a preference to indicate a default response address to be used? lilmatt: Won't it screw up reporting if the attendee address we send the invite to != the address of who reports back whether they're coming or not? I know people sometimes send invites to listservs, which is where this may come more into play.
  • TODO: Should there be a way to make one call and get all the preference information (perhaps returned as a comma delimited string) for a particular iTIP method and VComponent combination? lilmatt: *-delimited strings suck. Go do _anything_ with the categories preferences to see what I'm talking about. If there's a "one call and you get it all" method, it better return something complex enough to hold the data. In truth, this would be performance optimization we may not really need. How many times will you need to check a particular method/vcomp combo in one sitting?


TODO: Specify the values for these preferences

getItipPreference

  • Return type: AString
  • Returns the preference that the user asked for
  • Input Paramters: 2
  • Parameter 1: An ItipItem for reference
  • Parameter 2: A constant specifying which preference is being requested.
  • idl: AString getItipPrefernece(in calIItipItem itipItem, in unsigned long preferenceConstant);

process

  • Return type: void
  • Input Parameters: 1
  • Parameter 1: An ItipItem to process
  • idl: void process(in calIItipItem itipItem);
  • This call would process the ItipItem based on the structure it encapsulates.

Timezone Testing

In timezone testing, there are certain "safe" ranges for a zone and certain "unsafe" ranges for the zone. The safe ranges are those times during which the timezone calculation to UTC does not change the date. The unsafe ranges are those during which the timezone calculation to UTC does change the date. These unsafe ranges must be tested for all timezone conversion testing because you have a very good chance to find problems in those areas. For example, if you have a timezone that is offset -0600 hours from UTC (America/Chicago), then this is the range of safe and unsafe testing:

Unsafe and Safe Ranges for UTC-0600 Zone


0000 0100 0200 0300 0400 0500 0600 0700 0800 0900 1000 1100 1200 1300
<-------- unsafe --------------|<------- safe ---------------------->

1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 0000 0100 0200
------ safe --------->|<--------------- unsafe ---------------->

So, you want to be sure that your timezone tests test times during "safe" portions of a given timezone as well as "unsafe" parts of given timezones. But, I tend to focus attention on the unsafe areas, since this is usually where bugs are found. bug 349788 was found because of a problem in timezone calculations that only occurred when working with a time that was in the "unsafe" part of the day.

So, for timezone testing in general there are three good guidelines to follow:

  1. Test unsafe ranges of various zones
  2. Be sure to test negative offset zones as well as positive offset zones
  3. Test zones with weird offsets America/St. Johns (UTC-0330) and Asia/Kathmandu (UTC+0545) are some of my favorites.

And you can't talk about testing timezones without talking about testing daylight savings time rollovers. For that:

  1. Test that zones go into/out of daylight time on the proper days.
  2. Test southern zones as well as northern zones (see below)
  3. Test converting between zones that have daylight and zones that do not have daylight especially near the dates of daylight savings rollovers.
  4. Be sure to test all of this with both non-recurring (most likely to work) and recurring (least likely to work) events.

Diagram of how Northern Timezones and Southern Timezone daylight savings time differs.

Northern zone looks like this;
J   F   M   A   M   J   J   A   S   O   N   D
-noDst------|---------Dst-----------|---noDST--
            ^                       ^
         Dst Begins              Dst Ends

Southern zone is like this:
J   F   M   A   M   J   J   A   S   O   N   D
-Dst------|---------NoDst-----------|---DST--
          ^                         ^
       Dst Ends                  Dst Begins