diff --git a/src/WorkItemMigrator/WorkItemImport/Agent.cs b/src/WorkItemMigrator/WorkItemImport/Agent.cs index 0040aa2c..09cab1af 100644 --- a/src/WorkItemMigrator/WorkItemImport/Agent.cs +++ b/src/WorkItemMigrator/WorkItemImport/Agent.cs @@ -664,11 +664,11 @@ private bool ApplyAndSaveLinks(WiRevision rev, WorkItem wi, Settings settings) continue; } - if (link.Change == ReferenceChangeType.Added && !_witClientUtils.AddAndSaveLink(link, wi, settings)) + if (link.Change == ReferenceChangeType.Added && !_witClientUtils.AddAndSaveLink(link, wi, settings, rev.Author, rev.Time)) { success = false; } - else if (link.Change == ReferenceChangeType.Removed && !_witClientUtils.RemoveAndSaveLink(link, wi, settings)) + else if (link.Change == ReferenceChangeType.Removed && !_witClientUtils.RemoveAndSaveLink(link, wi, settings, rev.Author, rev.Time)) { success = false; } diff --git a/src/WorkItemMigrator/WorkItemImport/WitClient/WitClientUtils.cs b/src/WorkItemMigrator/WorkItemImport/WitClient/WitClientUtils.cs index 04b15215..70312b4d 100644 --- a/src/WorkItemMigrator/WorkItemImport/WitClient/WitClientUtils.cs +++ b/src/WorkItemMigrator/WorkItemImport/WitClient/WitClientUtils.cs @@ -57,7 +57,7 @@ public bool IsDuplicateWorkItemLink(IEnumerable links, WorkIte return true; } - public bool AddAndSaveLink(WiLink link, WorkItem wi, Settings settings) + public bool AddAndSaveLink(WiLink link, WorkItem wi, Settings settings, string author, DateTime time) { if (link == null) { @@ -86,7 +86,7 @@ public bool AddAndSaveLink(WiLink link, WorkItem wi, Settings settings) if (!IsDuplicateWorkItemLink(wi.Relations, relatedLink)) { wi.Relations.Add(relatedLink); - AddSingleLinkToWorkItemAndSave(link, wi, targetWorkItem, settings, "Imported link from JIRA"); + AddSingleLinkToWorkItemAndSave(link, wi, targetWorkItem, settings, "Imported link from JIRA", author, time); return true; } return false; @@ -98,11 +98,11 @@ public bool AddAndSaveLink(WiLink link, WorkItem wi, Settings settings) { if (ex2.Message.Contains("TF201036: You cannot add a Child link between work items")) { - ForceSwapLinkAndSave(link, wi, ex2, settings, Forward, GetWorkItem(link.TargetWiId), "child"); + ForceSwapLinkAndSave(link, wi, ex2, settings, Forward, GetWorkItem(link.TargetWiId), "child", author, time); } else if (ex2.Message.Contains("TF201036: You cannot add a Parent link between work items")) { - ForceSwapLinkAndSave(link, wi, ex2, settings, Reverse, GetWorkItem(link.SourceWiId), "parent"); + ForceSwapLinkAndSave(link, wi, ex2, settings, Reverse, GetWorkItem(link.SourceWiId), "parent", author, time); } else { @@ -122,7 +122,7 @@ public bool AddAndSaveLink(WiLink link, WorkItem wi, Settings settings) } - private void ForceSwapLinkAndSave(WiLink link, WorkItem wi, Exception ex2, Settings settings, string newLinkType, WorkItem wiTargetCurrent, string parentOrChild) + private void ForceSwapLinkAndSave(WiLink link, WorkItem wi, Exception ex2, Settings settings, string newLinkType, WorkItem wiTargetCurrent, string parentOrChild, string author, DateTime time) { Logger.Log(LogLevel.Warning, ex2.Message); Logger.Log(LogLevel.Warning, "Attempting to fix the above issue by removing the offending link and re-adding the correct link..."); @@ -140,12 +140,12 @@ private void ForceSwapLinkAndSave(WiLink link, WorkItem wi, Exception ex2, Setti TargetWiId = int.Parse(relation.Url.Split('/').Last()), WiType = "System.LinkTypes.Hierarchy-Reverse" }; - RemoveAndSaveLink(linkToRemove, wiTargetCurrent, settings); + RemoveAndSaveLink(linkToRemove, wiTargetCurrent, settings, author, time); // Add new link again var matchedRelations = wi.Relations.Where(r => r.Rel == "System.LinkTypes.Hierarchy-" + newLinkType && r.Url.Split('/').Last() == link.TargetWiId.ToString()); wi.Relations.Remove(matchedRelations.First()); - linkFixed = AddAndSaveLink(link, wi, settings); + linkFixed = AddAndSaveLink(link, wi, settings, author, time); break; } } @@ -161,7 +161,7 @@ private void ForceSwapLinkAndSave(WiLink link, WorkItem wi, Exception ex2, Setti } } - public bool RemoveAndSaveLink(WiLink link, WorkItem wi, Settings settings) + public bool RemoveAndSaveLink(WiLink link, WorkItem wi, Settings settings, string author, DateTime time) { if (link == null) { @@ -181,7 +181,7 @@ public bool RemoveAndSaveLink(WiLink link, WorkItem wi, Settings settings) Logger.Log(LogLevel.Warning, $"{link} - cannot identify link to remove for '{wi.Id}'."); return false; } - RemoveSingleLinkFromWorkItemAndSave(link, wi, settings); + RemoveSingleLinkFromWorkItemAndSave(link, wi, settings, author, time); wi.Relations.Remove(linkToRemove); return true; } @@ -1039,7 +1039,7 @@ private void RemoveSingleAttachmentFromWorkItemAndSave(WiAttachment att, WorkIte wi.Relations = result.Relations; } - private void AddSingleLinkToWorkItemAndSave(WiLink link, WorkItem sourceWI, WorkItem targetWI, Settings settings, string comment) + private void AddSingleLinkToWorkItemAndSave(WiLink link, WorkItem sourceWI, WorkItem targetWI, Settings settings, string comment, string changedBy, DateTime changedDate) { // Create a patch document for a new work item. // Specify a relation to the existing work item. @@ -1058,7 +1058,9 @@ private void AddSingleLinkToWorkItemAndSave(WiLink link, WorkItem sourceWI, Work comment } } - } + }, + JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedBy, changedBy), + JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedDate, changedDate) }; if (sourceWI.Id.HasValue) @@ -1069,7 +1071,7 @@ private void AddSingleLinkToWorkItemAndSave(WiLink link, WorkItem sourceWI, Work Logger.Log(LogLevel.Info, $"Updated new work item Id:{sourceWI.Id} with link to work item ID:{targetWI.Id}"); } - private void RemoveSingleLinkFromWorkItemAndSave(WiLink link, WorkItem sourceWI, Settings settings) + private void RemoveSingleLinkFromWorkItemAndSave(WiLink link, WorkItem sourceWI, Settings settings, string changedBy, DateTime changedDate) { WorkItemRelation rel = sourceWI.Relations.SingleOrDefault(a => a.Rel == link.WiType @@ -1091,7 +1093,9 @@ private void RemoveSingleLinkFromWorkItemAndSave(WiLink link, WorkItem sourceWI, { Operation = Operation.Remove, Path = "/relations/"+relIndex - } + }, + JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedBy, changedBy), + JsonPatchDocUtils.CreateJsonFieldPatchOp(Operation.Add, WiFieldReference.ChangedDate, changedDate) }; if (sourceWI.Id.HasValue) diff --git a/src/WorkItemMigrator/tests/Migration.Wi-Import.Tests/WitClient/WitClientUtilsTests.cs b/src/WorkItemMigrator/tests/Migration.Wi-Import.Tests/WitClient/WitClientUtilsTests.cs index cca45d23..7232eaa9 100644 --- a/src/WorkItemMigrator/tests/Migration.Wi-Import.Tests/WitClient/WitClientUtilsTests.cs +++ b/src/WorkItemMigrator/tests/Migration.Wi-Import.Tests/WitClient/WitClientUtilsTests.cs @@ -590,7 +590,7 @@ public void When_calling_add_link_with_empty_args_Then_an_exception_is_thrown() WitClientUtils wiUtils = new WitClientUtils(witClientWrapper); Assert.That( - () => wiUtils.AddAndSaveLink(null, null, null), + () => wiUtils.AddAndSaveLink(null, null, null, null, DateTime.Now), Throws.InstanceOf()); } @@ -615,7 +615,7 @@ public void When_calling_add_link_with_valid_args_Then_a_link_is_added() Change = ReferenceChangeType.Added }; - wiUtils.AddAndSaveLink(link, createdWI, settings); + wiUtils.AddAndSaveLink(link, createdWI, settings, "author", DateTime.Now); WorkItemRelation rel = createdWI.Relations[0]; @@ -659,7 +659,7 @@ public void When_calling_add_link_with_valid_args_and_an_attachment_is_present_o Change = ReferenceChangeType.Added }; - wiUtils.AddAndSaveLink(link, createdWI, settings); + wiUtils.AddAndSaveLink(link, createdWI, settings, "author", DateTime.Now); WorkItemRelation rel = createdWI.Relations.Where(rl => rl.Rel != "AttachedFile").Single(); @@ -703,7 +703,7 @@ public void When_calling_add_link_with_valid_args_and_an_attachment_is_present_o Change = ReferenceChangeType.Added }; - wiUtils.AddAndSaveLink(link, createdWI, settings); + wiUtils.AddAndSaveLink(link, createdWI, settings, "author", DateTime.Now); WorkItemRelation rel = createdWI.Relations[0]; @@ -721,7 +721,7 @@ public void When_calling_remove_link_with_empty_args_Then_an_exception_is_thrown WitClientUtils wiUtils = new WitClientUtils(witClientWrapper); Assert.That( - () => wiUtils.RemoveAndSaveLink(null, null, null), + () => wiUtils.RemoveAndSaveLink(null, null, null, null, DateTime.Now), Throws.InstanceOf()); } @@ -740,7 +740,7 @@ public void When_calling_remove_link_with_no_link_added_Then_false_is_returned() WiType = "System.LinkTypes.Hierarchy-Forward" }; - bool result = wiUtils.RemoveAndSaveLink(link, createdWI, settings); + bool result = wiUtils.RemoveAndSaveLink(link, createdWI, settings, "author", DateTime.Now); Assert.That(result, Is.EqualTo(false)); } @@ -766,9 +766,9 @@ public void When_calling_remove_link_with_link_added_Then_link_is_removed() Change = ReferenceChangeType.Added }; - wiUtils.AddAndSaveLink(link, createdWI, settings); + wiUtils.AddAndSaveLink(link, createdWI, settings, "author", DateTime.Now); - bool result = wiUtils.RemoveAndSaveLink(link, createdWI, settings); + bool result = wiUtils.RemoveAndSaveLink(link, createdWI, settings, "author", DateTime.Now); Assert.Multiple(() => {