public void TreeQueryOverInvalidTreeStructureThrowsExcpetion()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(0, 2),
                new Tuple <int, int>(0, 3),
                new Tuple <int, int>(1, 3),
                new Tuple <int, int>(1, 5),
                new Tuple <int, int>(5, 6),
                new Tuple <int, int>(3, 7)
            };
            ITfsWorkItem w1 = CreateWorkItem(1);
            ITfsWorkItem w2 = CreateWorkItem(2);
            ITfsWorkItem w3 = CreateWorkItem(3);
            ITfsWorkItem w4 = CreateWorkItem(4);
            ITfsWorkItem w5 = CreateWorkItem(5);
            ITfsWorkItem w6 = CreateWorkItem(6);
            ITfsWorkItem w7 = CreateWorkItem(7);

            ITfsWorkItem[] workItems = new ITfsWorkItem[] { w1, w2, w3, w4, w5, w6, w7 };

            QueryDefinition qd = this.SetupTreeQuery(links, workItems);

            // Act
            TestHelper.TestForInvalidOperationException(() => this.sut.QueryForWorkItems(qd, new CancellationToken()), "Query does not produce a well-formed tree.");
        }
예제 #2
0
        // TODO: add layout class more generally.

        /// <summary>
        /// Creates a work item tree node for testing.
        /// </summary>
        /// <param name="workItemType">The name of the work item type.</param>
        /// <param name="level">The level in the tree.</param>
        /// <returns>The work item tree node.</returns>
        private static WorkItemTreeNode CreateWorkItemNode(string workItemType, int level)
        {
            ITfsWorkItem     item = TestHelper.CreateMockWorkItem(workItemType, 1, "test");
            WorkItemTreeNode ans  = new WorkItemTreeNode(item, level);

            return(ans);
        }
 /// <summary>
 /// Refreshes the rich text content controls which are not bound to the Custom XML Parts.
 /// </summary>
 /// <param name="workItemManager">The work item manager that contains the new work items.</param>
 /// <param name="cancellationToken">Used to cancel the refresh.</param>
 private void RefreshRichTextContentControls(WorkItemManager workItemManager, CancellationToken cancellationToken)
 {
     this.logger.Log(TraceEventType.Verbose, "Refreshing rich text content controls");
     foreach (ContentControl c in this.wordDocument.AllContentControls())
     {
         cancellationToken.ThrowIfCancellationRequested();
         if (c.Type == WdContentControlType.wdContentControlRichText)
         {
             Match m = RichTextContentControlTagPattern.Match(c.Tag);
             if (m.Success)
             {
                 string       fieldName = m.Groups["fieldName"].Captures[0].Value;
                 int          id        = int.Parse(m.Groups["id"].Captures[0].Value, CultureInfo.InvariantCulture);
                 ITfsWorkItem workItem  = workItemManager[id];
                 if (workItem != null)
                 {
                     if (workItem.FieldReferenceNames.Contains(fieldName))
                     {
                         this.wordDocument.PopulateRichTextContentControlWithHtml(c, workItem[fieldName].ToString());
                     }
                 }
                 else
                 {
                     this.wordDocument.PopulateRichTextContentControlWithHtml(c, string.Empty);
                 }
             }
         }
     }
 }
        public void AddThrowsExceptionForANullArgument()
        {
            // Arrange
            ITfsWorkItem nullItem = null;

            // Act and Assert
            TestHelper.TestForArgumentNullException(() => this.sut.AddRange(nullItem), "workItem");
        }
예제 #5
0
        /// <summary>
        /// Gets the no. of changesets for a given work item (fast than fetching all)
        /// </summary>
        /// <param name="workItem">The work item to query</param>
        /// <returns>The list of changesets</returns>
        public int GetRelatedChangesetsForWorkItemCount(ITfsWorkItem workItem)
        {
            var changesetLinkType = TfsWorkItemStore.RegisteredLinkTypes[ArtifactLinkIds.Changeset];
            var artifactProvider  = VersionControlServer.ArtifactProvider;

            return
                (workItem.WorkItem.Links.OfType <ExternalLink>().Where(type => type.ArtifactLinkType.Equals(changesetLinkType)).Count());
        }
예제 #6
0
 /// <summary>
 /// Gets the work item with the given id.
 /// </summary>
 /// <param name="id">The id of the work item to retrieve.</param>
 /// <returns>The work item with the given id.</returns>
 public ITfsWorkItem this[int id]
 {
     get
     {
         ITfsWorkItem ans = null;
         this.workItemList.TryGetValue(id, out ans);
         return(ans);
     }
 }
예제 #7
0
        /// <summary>
        /// Returns the list of related changesets for a given work item
        /// </summary>
        /// <param name="workItem">The work item to query</param>
        /// <returns>The list of changesets</returns>
        public IEnumerable <ITfsChangeset> GetRelatedChangesetsForWorkItem(ITfsWorkItem workItem)
        {
            var changesetLinkType = TfsWorkItemStore.RegisteredLinkTypes[ArtifactLinkIds.Changeset];
            var artifactProvider  = VersionControlServer.ArtifactProvider;

            return
                (workItem.WorkItem.Links
                 .OfType <ExternalLink>()
                 .Where(type => type.ArtifactLinkType.Equals(changesetLinkType))
                 .Select(link => new TfsChangeset(artifactProvider.GetChangeset(new Uri(link.LinkedArtifactUri)))));
        }
        public void CanAddAWorkItemToTheManager()
        {
            // Arrange
            ITfsWorkItem item = TestHelper.CreateMockWorkItem(1);

            // Act
            this.sut.Add(item);

            // Assert
            Assert.AreEqual <int>(1, this.sut.WorkItems.Count(), "There should be 1 work item stored by the manager now");
            Assert.AreSame(item, this.sut.WorkItems.First(), "Work item not stored in the manager");
        }
        public void CanAddMoreThanOneWorkItemToTheManagerAtTheSameTime()
        {
            // Arrange
            ITfsWorkItem item1 = TestHelper.CreateMockWorkItem(1);
            ITfsWorkItem item2 = TestHelper.CreateMockWorkItem(2);

            // Act
            this.sut.AddRange(item1, item2);

            // Assert
            Assert.AreEqual <int>(2, this.sut.WorkItems.Count(), "There should be 2 work items stored by the manager now");
            Assert.IsTrue(TestHelper.CheckUnorderedUniqueArrayMatch <ITfsWorkItem>(new ITfsWorkItem[] { item1, item2 }, this.sut.WorkItems.ToArray()), "Work items stored by manager do not match those passed to the Add call.");
        }
        public void LookupReturnsNullForNonExistentWorkItemId()
        {
            // Arrange
            ITfsWorkItem item1 = TestHelper.CreateMockWorkItem(1);

            this.sut.Add(item1);

            // Act
            ITfsWorkItem ans = this.sut[2];

            // Assert
            Assert.IsNull(ans, "Expect null for work item id that does not exist.");
        }
        public void ClearRemovesItems()
        {
            // Arrange
            ITfsWorkItem item = TestHelper.CreateMockWorkItem(1);

            this.sut.Add(item);

            // Act
            this.sut.Clear();

            // Assert
            Assert.AreEqual <int>(0, this.sut.WorkItems.Count(), "There should not be any work items stored by the manager now");
        }
        public void TreeQueryReturnsItemsInTreeStructure()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(0, 2),
                new Tuple <int, int>(0, 3),
                new Tuple <int, int>(1, 4),
                new Tuple <int, int>(1, 5),
                new Tuple <int, int>(4, 6),
                new Tuple <int, int>(3, 7)
            };
            ITfsWorkItem w1 = CreateWorkItem(1);
            ITfsWorkItem w2 = CreateWorkItem(2);
            ITfsWorkItem w3 = CreateWorkItem(3);
            ITfsWorkItem w4 = CreateWorkItem(4);
            ITfsWorkItem w5 = CreateWorkItem(5);
            ITfsWorkItem w6 = CreateWorkItem(6);
            ITfsWorkItem w7 = CreateWorkItem(7);

            ITfsWorkItem[] workItems = new ITfsWorkItem[] { w1, w2, w3, w4, w5, w6, w7 };

            QueryDefinition qd = this.SetupTreeQuery(links, workItems);

            // Act
            WorkItemTree ans = this.sut.QueryForWorkItems(qd, new CancellationToken());

            // Assert
            Assert.AreEqual <int>(3, ans.RootNodes.Count, "Incorrect number of root nodes returned");
            Assert.AreEqual <int>(1, ans.RootNodes[0].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(2, ans.RootNodes[0].Children.Count, "Invalid tree structure returned");

            Assert.AreEqual <int>(4, ans.RootNodes[0].Children[0].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(1, ans.RootNodes[0].Children[0].Children.Count, "Invalid tree structure returned");

            Assert.AreEqual <int>(6, ans.RootNodes[0].Children[0].Children[0].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(0, ans.RootNodes[0].Children[0].Children[0].Children.Count, "Invalid tree structure returned");

            Assert.AreEqual <int>(5, ans.RootNodes[0].Children[1].WorkItem.Id, "Invalid tree structure returned");

            Assert.AreEqual <int>(2, ans.RootNodes[1].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(0, ans.RootNodes[1].Children.Count, "Invalid tree structure returned");

            Assert.AreEqual <int>(3, ans.RootNodes[2].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(1, ans.RootNodes[2].Children.Count, "Invalid tree structure returned");

            Assert.AreEqual <int>(7, ans.RootNodes[2].Children[0].WorkItem.Id, "Invalid tree structure returned");
            Assert.AreEqual <int>(0, ans.RootNodes[2].Children[0].Children.Count, "Invalid tree structure returned");
        }
        public void TreeQueryModifiesQueryToWorkItemStoreToJustGetDisplayFields()
        {
            // Arrange
            Tuple <int, int>[] links     = new Tuple <int, int> [0];
            ITfsWorkItem[]     workItems = new ITfsWorkItem[0];

            QueryDefinition qd = this.SetupTreeQuery(links, workItems, new string[] { "[field1]", "[field2]" });

            // Act
            WorkItemTree ans = this.sut.QueryForWorkItems(qd, new CancellationToken());

            // Assert
            this.mockQuery.Verify(q => q.WorkItemStore.Query(It.IsAny <int[]>(), It.Is <string>(s => s == "SELECT [field1], [field2] FROM WorkItems")));
        }
        public void AddOverwritesExistingWorkItemWithSameId()
        {
            // Arrange
            ITfsWorkItem item1 = TestHelper.CreateMockWorkItem(1);
            ITfsWorkItem item2 = TestHelper.CreateMockWorkItem(1);

            // Act
            this.sut.Add(item1);
            this.sut.Add(item2);

            // Assert
            Assert.AreEqual <int>(1, this.sut.WorkItems.Count(), "There should be only 1 work item stored by the manager now");
            Assert.AreSame(item2, this.sut.WorkItems.First(), "Work item not stored in the manager");
        }
예제 #15
0
        public void CanGetFullHistoryOfAWorkItem()
        {
            // Arrange
            QueryDefinition query = new QueryDefinition("Test", TestHelper.AllFieldTypesQuery + " WHERE [System.Id] = 21406");

            // Act
            WorkItemTree ans = this.sut.QueryRunner.QueryForWorkItems(query, new CancellationToken());

            // Assert
            ITfsWorkItem item   = ans.DepthFirstNodes().First().WorkItem;
            string       expect = @"<html><head/><body>11/03/2011 10:25:11 Resolved with changeset 24111.<br>11/03/2011 10:19:43 &lt;no comment&gt;<br>10/03/2011 10:16:27 Associated with changeset 23952.<br>10/03/2011 10:14:22 Did some research and need some advice from the Word Product Group. Have sent email and now awaiting response.<br>10/03/2011 09:21:46 &lt;no comment&gt;<br></body></html>";

            Assert.AreEqual(expect, item["System.History"], "History not correct");
        }
        public void CanLookupByWorkItemId()
        {
            // Arrange
            ITfsWorkItem item1 = TestHelper.CreateMockWorkItem(1);
            ITfsWorkItem item2 = TestHelper.CreateMockWorkItem(2);

            this.sut.Add(item1);
            this.sut.Add(item2);

            // Act
            ITfsWorkItem ans = this.sut[2];

            // Assert
            Assert.AreSame(item2, ans, "Failed to lookup by work item id");
        }
예제 #17
0
        public void HtmlFieldGetsHtmlTagWrapper()
        {
            // Arrange
            QueryDefinition query = new QueryDefinition("Test", TestHelper.AllFieldTypesQuery + " WHERE [System.Id] = 21404");

            // Act
            WorkItemTree ans = this.sut.QueryRunner.QueryForWorkItems(query, new CancellationToken());

            // Assert
            ITfsWorkItem item   = ans.DepthFirstNodes().First().WorkItem;
            string       actual = item["Microsoft.VSTS.TCM.ReproSteps"].ToString();

            Assert.IsTrue(actual.StartsWith("<html><head/><body><P"), "Field is not well-formed HTML, field content is: " + actual);
            Assert.IsTrue(actual.EndsWith("</P></body></html>"), "Field is not well-formed HTML, field content is: " + actual);
        }
예제 #18
0
        /// <summary>
        /// Serializes a work item to XML.
        /// </summary>
        /// <remarks>
        /// The work item id and type are always serialized, regardless of which other fields are to be serialized.
        /// </remarks>
        /// <param name="workItem">The work item to be serialized.</param>
        /// <param name="fieldNames">The names of fields to serialize.</param>
        /// <returns>The XElement that represents the work item.</returns>
        public static XElement Serialize(ITfsWorkItem workItem, params string[] fieldNames)
        {
            if (workItem == null)
            {
                throw new ArgumentNullException("workItem");
            }

            fieldNames = fieldNames.Union(new string[] { Constants.SystemIdFieldReferenceName, Constants.SystemWorkItemTypeFieldReferenceName }).ToArray();

            XElement ans = new XElement(
                workItemNamespace + "WorkItem",
                fieldNames.Where(fieldName => workItem.FieldReferenceNames.Contains(fieldName)).Select(fieldName => SerializeField(workItem, fieldName)));

            return(ans);
        }
        public void AddRangeWithDuplicatesInListBeingAddedOverwritesEarlierWorkItemWithSameId()
        {
            // Arrange
            ITfsWorkItem item1 = TestHelper.CreateMockWorkItem(1);
            ITfsWorkItem item2 = TestHelper.CreateMockWorkItem(2);
            ITfsWorkItem item3 = TestHelper.CreateMockWorkItem(1);
            ITfsWorkItem item4 = TestHelper.CreateMockWorkItem(2);
            ITfsWorkItem item5 = TestHelper.CreateMockWorkItem(3);

            // Act
            this.sut.AddRange(item1, item2, item3, item4, item5);

            // Assert
            Assert.AreEqual <int>(3, this.sut.WorkItems.Count(), "There should be only 3 work item stored by the manager now");
            Assert.IsTrue(TestHelper.CheckUnorderedUniqueArrayMatch <ITfsWorkItem>(new ITfsWorkItem[] { item3, item4, item5 }, this.sut.WorkItems.ToArray()), "Work items not overwritten.");
        }
        public void OneHopQueryMustStartWithARootNode()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(1, 2)
            };
            ITfsWorkItem w1 = CreateWorkItem(1);
            ITfsWorkItem w2 = CreateWorkItem(2);

            ITfsWorkItem[] workItems = new ITfsWorkItem[] { w1, w2 };

            QueryDefinition qd = this.SetupOneHopQuery(links, workItems);

            // Act
            TestHelper.TestForInvalidOperationException(() => this.sut.QueryForWorkItems(qd, new CancellationToken()), "Query does not produce a well-formed direct link structure.");
        }
예제 #21
0
        /// <summary>
        /// Adds a new work item to the manager.
        /// </summary>
        /// <remarks>
        /// Existing work items with the same work item id are replaced.
        /// </remarks>
        /// <param name="workItem">The work item to be added.</param>
        public void Add(ITfsWorkItem workItem)
        {
            if (workItem == null)
            {
                throw new ArgumentNullException("workItem");
            }

            ITfsWorkItem existingItem = null;

            this.workItemList.TryGetValue(workItem.Id, out existingItem);
            if (existingItem != null)
            {
                this.workItemList.Remove(workItem.Id);
            }

            this.workItemList.Add(workItem.Id, workItem);
        }
        public void FlatQueryReturnsWorkItemsInFlatStructure()
        {
            // Arrange
            ITfsWorkItem    w1 = CreateWorkItem(1);
            ITfsWorkItem    w2 = CreateWorkItem(2);
            ITfsWorkItem    w3 = CreateWorkItem(3);
            QueryDefinition qd = this.SetupFlatQuery(w1, w2, w3);

            // Act
            WorkItemTree ans = this.sut.QueryForWorkItems(qd, new CancellationToken());

            // Assert
            Assert.AreEqual <int>(3, ans.RootNodes.Count, "Incorrect number of root nodes returned");
            Assert.AreEqual <int>(w1.Id, ans.RootNodes[0].WorkItem.Id);
            Assert.AreEqual <int>(w2.Id, ans.RootNodes[1].WorkItem.Id);
            Assert.AreEqual <int>(w3.Id, ans.RootNodes[2].WorkItem.Id);
        }
        public void OneHopQueryDoesNotAllowNestingMoreThanOneLevel()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(1, 2),
                new Tuple <int, int>(2, 3)
            };
            ITfsWorkItem w1 = CreateWorkItem(1);
            ITfsWorkItem w2 = CreateWorkItem(2);
            ITfsWorkItem w3 = CreateWorkItem(3);

            ITfsWorkItem[] workItems = new ITfsWorkItem[] { w1, w2, w3 };

            QueryDefinition qd = this.SetupOneHopQuery(links, workItems);

            // Act
            TestHelper.TestForInvalidOperationException(() => this.sut.QueryForWorkItems(qd, new CancellationToken()), "Query does not produce a well-formed direct link structure.");
        }
        public void TreeQueryWithDuplicateLinkIdsPassedDedupedArrayToWorkItemStoreQuery()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(0, 3),
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(0, 2),
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(0, 2)
            };
            ITfsWorkItem[] workItems = new ITfsWorkItem[] { CreateWorkItem(1), CreateWorkItem(2), CreateWorkItem(3) };

            QueryDefinition qd = this.SetupTreeQuery(links, workItems);

            // Act
            WorkItemTree ans = this.sut.QueryForWorkItems(qd, new CancellationToken());

            // Assert
            this.mockQuery.Verify(q => q.WorkItemStore.Query(TestHelper.UnorderedUniqueArray <int>(1, 2, 3), It.IsAny <string>()));
        }
예제 #25
0
        /// <summary>
        /// Runs a tree query.
        /// </summary>
        /// <param name="query">The query to execute.</param>
        /// <param name="cancellationToken">Used to cancel the operation.</param>
        /// <returns>A tree of work items.</returns>
        private static WorkItemTree RunTreeQuery(ITfsQuery query, CancellationToken cancellationToken)
        {
            WorkItemTree ans = new WorkItemTree();

            WorkItemLinkInfo[] wilis = query.RunLinkQuery(cancellationToken);
            int[] ids = new int[wilis.Length];
            for (int i = 0; i < ids.Length; i++)
            {
                ids[i] = wilis[i].TargetId;
            }

            string workItemQueryString     = QueryUtilities.ConvertTreeQueryToQueryForItem(query);
            IList <ITfsWorkItem> workItems = query.WorkItemStore.Query(ids.Distinct().ToArray(), workItemQueryString);

            for (int i = 0; i < wilis.Length; i++)
            {
                WorkItemLinkInfo wili = wilis[i];
                ITfsWorkItem     wi   = workItems.Select(item => item).Where(item => item.Id == wili.TargetId).Single();
                if (wili.SourceId <= 0)
                {
                    ans.RootNodes.Add(new WorkItemTreeNode(wi, 0));
                }
                else
                {
                    WorkItemTreeNode parent = null;
                    try
                    {
                        parent = ans.DepthFirstNodes().Where(node => node.WorkItem.Id == wili.SourceId).Single();
                    }
                    catch (InvalidOperationException)
                    {
                        throw new InvalidOperationException(ModelResources.QueryNotWellFormedTree);
                    }

                    parent.Children.Add(new WorkItemTreeNode(wi, parent.Level + 1));
                }
            }

            return(ans);
        }
        public void TreeQueryBuildsTreeCorrectlyEvenIfWorkItemsReturnedInADifferentOrder()
        {
            // Arrange
            Tuple <int, int>[] links = new Tuple <int, int>[]
            {
                new Tuple <int, int>(0, 1),
                new Tuple <int, int>(0, 2),
                new Tuple <int, int>(0, 3)
            };
            ITfsWorkItem[] workItems = new ITfsWorkItem[] { CreateWorkItem(3), CreateWorkItem(2), CreateWorkItem(1) };

            QueryDefinition qd = this.SetupTreeQuery(links, workItems);

            // Act
            WorkItemTree ans = this.sut.QueryForWorkItems(qd, new CancellationToken());

            // Assert
            Assert.AreEqual <int>(3, ans.RootNodes.Count, "Incorrect number of root nodes returned");
            Assert.AreEqual <int>(1, ans.RootNodes[0].WorkItem.Id);
            Assert.AreEqual <int>(2, ans.RootNodes[1].WorkItem.Id);
            Assert.AreEqual <int>(3, ans.RootNodes[2].WorkItem.Id);
        }
예제 #27
0
        /// <summary>
        /// Serializes a field from a work item.
        /// </summary>
        /// <param name="workItem">The work item containing the field to be serialized.</param>
        /// <param name="fieldName">The name of the field to be serialized.</param>
        /// <returns>The serialized field.</returns>
        private static XElement SerializeField(ITfsWorkItem workItem, string fieldName)
        {
            XElement ans = new XElement(workItemNamespace + Constants.WorkItemFieldElementName, new XAttribute(Constants.WorkItemFieldNameAttributeName, fieldName), workItem[fieldName]);

            return(ans);
        }
예제 #28
0
 public TfsWorkItemWrapper(ITfsWorkItem source)
     : base(typeof(TfsWorkItemWrapper))
 {
     _tfsWorkItem = source;
 }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WorkItemTreeNode"/> class.
 /// </summary>
 /// <param name="workItem">The work item represented at this node.</param>
 /// <param name="level">The level in the tree, 0 is the highest level in the tree</param>
 public WorkItemTreeNode(ITfsWorkItem workItem, int level)
 {
     this.WorkItem = workItem;
     this.Level    = level;
     this.Children = new List <WorkItemTreeNode>();
 }