Skip to content

Add comment to work item together with information about the sender #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Documentation/FullyAnnotatedConfigReference.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,12 @@
- Subject - The email subject
- MessageBody - The body of the email message converted to plain text (i.e. if the body was HTML,
it would be stripped to plain text)
- MessageBodyWithSender - Similar to MessageBody, but with an added line at the bottom mentioning the
- MessageBodyWithSender - Similar to MessageBody, but with an added line at the top mentioning the
display name and email address of the sender. Useful to include indication of the person whose email
triggered the work item creation
- MessageLastReply - Last reply of the thread
- MessageLastReplyWithSender - Similar to MessageLastReply, but with an added line at the top mentioning the
display name and email address of the sender.
- RawMessageBody - The raw body of the email - i.e. if it's an HTML message, this would be the full
message HTML
- Now - Current date time in general ("g") date time format (see
Expand All @@ -126,6 +129,16 @@
<DefaultValueDefinition Field="Iteration Path" Value="HelloWorldProject\Iteration 42" />
<DefaultValueDefinition Field="Description" Value="##MessageBody" />
</DefaultFieldValues>


<!--
DefaultFieldValuesOnUpdate is analogous to DefaultFieldValues, the values are used when an update is made
to an existing work item. There are no mandatory fields for this setting.
-->
<DefaultFieldValuesOnUpdate>
<!-- Last reply is set as comment, together with the information about the sender -->
<DefaultValueDefinition Field="History" Value="##MessageLastReplyWithSender" />
</DefaultFieldValuesOnUpdate>
<!-- Mnemonics allow you to define short strings that users can put in the email to set specific fields to
predefined values without the need for verbose explicit overrides. A single mnemonic can set one specific
field, or several fieds. To have a single mnemonic set several fields, just add multiple MnemonicDefinition
Expand Down
3 changes: 3 additions & 0 deletions Documentation/Mail2BugConfigExample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<DefaultValueDefinition Field="Iteration Path" Value="HelloWorldProject\Iteration 42" />
<DefaultValueDefinition Field="Description" Value="##MessageBody" />
</DefaultFieldValues>

<DefaultFieldValuesOnUpdate>
</DefaultFieldValuesOnUpdate>
<!-- 'true' means we should attached the email message that triggered the creation of the work item -->
<AttachOriginalMessage>true</AttachOriginalMessage>
</WorkItemSettings>
Expand Down
1 change: 1 addition & 0 deletions Mail2Bug/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public enum ProcessingStrategyType

public string ConversationIndexFieldName { get; set; }
public List<DefaultValueDefinition> DefaultFieldValues { get; set; }
public List<DefaultValueDefinition> DefaultFieldValuesOnUpdate { get; set; }
public List<MnemonicDefinition> Mnemonics { get; set; }
public List<RecipientOverrideDefinition> RecipientOverrides { get; set; }
public List<DateBasedFieldOverrides> DateBasedOverrides { get; set; }
Expand Down
15 changes: 12 additions & 3 deletions Mail2Bug/MessageProcessingStrategies/SimpleBugStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ private void InitWorkItemFields(IIncomingEmailMessage message, Dictionary<string
}
}

private void InitWorkItemUpdateFields(SpecialValueResolver resolver, IDictionary<string, string> workItemUpdates)
{
foreach (var defaultFieldValue in _config.WorkItemSettings.DefaultFieldValuesOnUpdate)
{
workItemUpdates[defaultFieldValue.Field] = resolver.Resolve(defaultFieldValue.Value);
}
}

private void TryApplyFieldOverrides(Dictionary<string, string> overrides, int workItemId)
{
if (overrides.Count == 0)
Expand All @@ -115,7 +123,7 @@ private void TryApplyFieldOverrides(Dictionary<string, string> overrides, int wo
try
{
Logger.DebugFormat("Overrides found. Calling 'ModifyWorkItem'");
_workItemManager.ModifyWorkItem(workItemId, "", overrides);
_workItemManager.ModifyWorkItem(workItemId, overrides);
}
catch (Exception ex)
{
Expand All @@ -131,6 +139,8 @@ private void UpdateWorkItem(IIncomingEmailMessage message, int workItemId)
var resolver = new SpecialValueResolver(message, _workItemManager.GetNameResolver());
var workItemUpdates = new Dictionary<string, string>();

InitWorkItemUpdateFields(resolver, workItemUpdates);

if (_config.WorkItemSettings.OverrideChangedBy)
{
workItemUpdates["Changed By"] = resolver.Sender;
Expand All @@ -146,8 +156,7 @@ private void UpdateWorkItem(IIncomingEmailMessage message, int workItemId)
overrides.ToList().ForEach(x => workItemUpdates[x.Key] = x.Value);
}

// Construct the text to be appended
_workItemManager.ModifyWorkItem(workItemId, message.GetLastMessageText(), workItemUpdates);
_workItemManager.ModifyWorkItem(workItemId, workItemUpdates);

ProcessAttachments(message, workItemId);

Expand Down
17 changes: 13 additions & 4 deletions Mail2Bug/MessageProcessingStrategies/SpecialValueResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class SpecialValueResolver

public const string SubjectKeyword = "##Subject";
public const string SenderKeyword = "##Sender";
public const string MessageLastReplyKeyword = "##MessageLastReply";
public const string MessageLastReplyWithSenderKeyword = "##MessageLastReplyWithSender";
public const string MessageBodyKeyword = "##MessageBody";
public const string MessageBodyWithSenderKeyword = "##MessageBodyWithSender";
public const string RawMessageBodyKeyword = "##RawMessageBody";
Expand All @@ -30,12 +32,12 @@ public SpecialValueResolver(IIncomingEmailMessage message, INameResolver resolve
_valueResolutionMap = new Dictionary<string, string>();
_valueResolutionMap[SubjectKeyword] = GetValidSubject(message);
_valueResolutionMap[SenderKeyword] = GetSender(message);
_valueResolutionMap[MessageLastReplyKeyword] = TextUtils.FixLineBreaks(message.GetLastMessageText());
_valueResolutionMap[MessageLastReplyWithSenderKeyword] =
GetMessageWithSender(_valueResolutionMap[MessageLastReplyKeyword], message.SenderName, message.SenderAddress);
_valueResolutionMap[MessageBodyKeyword] = TextUtils.FixLineBreaks(message.PlainTextBody);
_valueResolutionMap[MessageBodyWithSenderKeyword] =
String.Format("{0}\n\nCreated by: {1} ({2})",
_valueResolutionMap[MessageBodyKeyword],
message.SenderName,
message.SenderAddress);
GetMessageWithSender(_valueResolutionMap[MessageBodyKeyword], message.SenderName, message.SenderAddress);
_valueResolutionMap[RawMessageBodyKeyword] = TextUtils.FixLineBreaks(message.RawBody);
_valueResolutionMap[NowKeyword] = DateTime.Now.ToString("g");
_valueResolutionMap[TodayKeyword] = DateTime.Now.ToString("d");
Expand Down Expand Up @@ -91,6 +93,13 @@ private static string GetValidSubject(IIncomingEmailMessage message)
return !string.IsNullOrEmpty(message.ConversationTopic) ? message.ConversationTopic : "NO SUBJECT";
}

private static string GetMessageWithSender(string message, string sender, string senderAddress)
{
var formatted = string.Format("Created by: {1} ({2})\n\n{0}", message, sender, senderAddress);

return formatted;
}

private string GetValidTimeString(DateTime? dateTime)
{
if (dateTime.HasValue)
Expand Down
3 changes: 1 addition & 2 deletions Mail2Bug/WorkItemManagement/IWorkItemManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ public interface IWorkItemManager
int CreateWorkItem(Dictionary<string, string> values);

/// <param name="workItemId">The ID of the bug to modify </param>
/// <param name="comment">Comment to add to description</param>
/// <param name="values">List of fields to change</param>
void ModifyWorkItem(int workItemId, string comment, Dictionary<string, string> values);
void ModifyWorkItem(int workItemId, Dictionary<string, string> values);

INameResolver GetNameResolver();
}
Expand Down
8 changes: 3 additions & 5 deletions Mail2Bug/WorkItemManagement/TFSWorkItemManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,17 +241,15 @@ public int CreateWorkItem(Dictionary<string, string> values)
}

/// <param name="workItemId">The ID of the work item to modify </param>
/// <param name="comment">Comment to add to description</param>
/// <param name="values">List of fields to change</param>
public void ModifyWorkItem(int workItemId, string comment, Dictionary<string, string> values)
public void ModifyWorkItem(int workItemId, Dictionary<string, string> values)
{
if (workItemId <= 0) return;

var workItem = _tfsStore.GetWorkItem(workItemId);

workItem.Open();

workItem.History = comment.Replace("\n", "<br>");
foreach (var key in values.Keys)
{
TryApplyFieldValue(workItem, key, values[key]);
Expand Down Expand Up @@ -373,9 +371,9 @@ private static void TryApplyFieldValue(WorkItem workItem, string key, string val
return;
}

if (field.FieldDefinition.FieldType == FieldType.Html)
if (field.FieldDefinition.FieldType == FieldType.Html || field.FieldDefinition.FieldType == FieldType.History)
{
value = value.Replace("\n", "<br>");
value = value.Replace("\n", "<br />");
}

field.Value = value;
Expand Down
9 changes: 1 addition & 8 deletions Mail2Bug/WorkItemManagement/WorkItemManagerMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public int CreateWorkItem(Dictionary<string, string> values)
return id;
}

public void ModifyWorkItem(int workItemId, string comment, Dictionary<string, string> values)
public void ModifyWorkItem(int workItemId, Dictionary<string, string> values)
{
if (ThrowOnModifyBug != null) throw ThrowOnModifyBug;

Expand All @@ -89,13 +89,6 @@ public void ModifyWorkItem(int workItemId, string comment, Dictionary<string, st
{
bugEntry[key] = values[key];
}

if (!bugEntry.ContainsKey(HistoryField))
{
bugEntry[HistoryField] = "";
}

bugEntry[HistoryField] += comment;
}

public INameResolver GetNameResolver()
Expand Down
8 changes: 4 additions & 4 deletions Mail2BugUnitTests/SimpleBugStrategyUnitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void TestSpecialValues()
ValidateBugValue(bugValues, nowField, DateTime.Now.ToString("g"));
ValidateBugValue(bugValues, todayField, DateTime.Now.ToString("d"));
ValidateBugValue(bugValues, messageBodyField, message.PlainTextBody);
ValidateBugValue(bugValues, messageBodyWithSenderField, String.Format("{0}\n\nCreated by: {1} ({2})", message.PlainTextBody, message.SenderName, message.SenderAddress));
ValidateBugValue(bugValues, messageBodyWithSenderField, String.Format("Created by: {1} ({2})\n\n{0}", message.PlainTextBody, message.SenderName, message.SenderAddress));
ValidateBugValue(bugValues, senderField, message.SenderName);
ValidateBugValue(bugValues, subjectField, message.ConversationTopic);
}
Expand Down Expand Up @@ -201,7 +201,7 @@ public void TestProcessingEmailThreadImpl(bool overrideChangedBy)
{
expectedValues["Changed By"] = message3.SenderName;
}
expectedValues[WorkItemManagerMock.HistoryField] = TextUtils.FixLineBreaks(message2.GetLastMessageText() + message3.GetLastMessageText());
expectedValues[WorkItemManagerMock.HistoryField] = TextUtils.FixLineBreaks(message3.GetLastMessageText());

ValidateBugValues(expectedValues, bugFields);
}
Expand Down Expand Up @@ -249,7 +249,7 @@ public void TestApplyingOverridesInUpdateMessage()

expectedValues["Changed By"] = message4.SenderName;
expectedValues[WorkItemManagerMock.HistoryField] =
TextUtils.FixLineBreaks(message2.GetLastMessageText() + message3.GetLastMessageText() + message4.GetLastMessageText());
TextUtils.FixLineBreaks(message4.GetLastMessageText());
expectedValues[mnemonicDef.Field] = mnemonicDef.Value;
expectedValues[explicitOverride1.Key] = explicitOverride1.Value;

Expand Down Expand Up @@ -284,7 +284,7 @@ public void TestAttachingUpdateMessages()

expectedValues["Changed By"] = message3.SenderName;
expectedValues[WorkItemManagerMock.HistoryField] =
TextUtils.FixLineBreaks(message2.GetLastMessageText() + message3.GetLastMessageText());
TextUtils.FixLineBreaks(message3.GetLastMessageText());

ValidateBugValues(expectedValues, bugFields);

Expand Down
3 changes: 3 additions & 0 deletions Mail2BugUnitTests/SimpleBugStrategyUnitTestConfig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<DefaultFieldValues>
<DefaultValueDefinition Field="Assigned To" Value="ABCD" />
</DefaultFieldValues>
<DefaultFieldValuesOnUpdate>
<DefaultValueDefinition Field="History" Value="##MessageLastReply" />
</DefaultFieldValuesOnUpdate>
</WorkItemSettings>
<EmailSettings>
<ServiceType>EWSByRecipients</ServiceType>
Expand Down