Task.Complete() Bug
I was testing the application and came across a bug; whenever you complete a reoccurring item, it uses a faulty algorithm.
public void Complete()
{
MetadataAttribute dueDateAttribute = this.Attributes["DueDate"];
if (dueDateAttribute != null && dueDateAttribute.Value != null)
{
int unit = 0;
if (this.Attributes.Contains("ReoccurrenceUnit"))
unit = this.Attributes["ReoccurrenceUnit"].GetValue<int>();
if (unit > 0)
dueDateAttribute.Value = dueDateAttribute.GetValue<DateTime>().AddDays(Convert.ToInt32(unit));
else
this.Attributes.Remove(dueDateAttribute);
}
this.OnTaskCompleted(EventArgs.Empty);
}
There are some bugs with this; first off, I got rid of ReoccurrenceUnit, changing it to ReoccurrenceAmount instead! I don't know how this got missed. But that is a problem with using a collection as your property values; these are bugs that are harder to find. This kind of problem couldn't have been caught by the test either because it ensure you enter in the correct key value, which I didn't. I will place more provisions on that later; however, it will be working now.
The other problem is that it makes no use of the IsReoccurring value, which should be the true test. Instead, it looks for the measurement value. The refactored method now looks like this:
public void Complete()
{
//Get the due date attribute
MetadataAttribute dueDateAttribute = this.Attributes["DueDate"];
//If this is a reoccurring task
if (this.GetAttributeValue<bool>("IsReoccurring"))
{
//Get the amount of reoccurrence from the attributes
int amount = this.GetAttributeValue<int>("ReoccurrenceAmount");
//If the amount is a positive number
if (amount > 0)
//Add the amount to the date
dueDateAttribute.Value = dueDateAttribute.GetValue<DateTime>().AddDays(Convert.ToDouble(amount));
else
//No amount provided; throw an error
throw new ArgumentException("The reoccurrence amount is not a positive amount", "ReoccurrenceAmount attribute");
}
else
//The task is completed, so remove the date attribute from the
//collection; this means that it is completed
this.Attributes.Remove(dueDateAttribute);
this.OnTaskCompleted(EventArgs.Empty);
}
A quick test verifies that this works.