protected override IEnumerable <IWorkItemEvent> ClassifyInternal(WorkItemResolutionRequest request)
        {
            var resolutionUpdate = request.WorkItem.Updates.LastOrDefault(u => WasResolvedByTeamMember(u, request));

            if (resolutionUpdate == null)
            {
                return(Enumerable.Empty <IWorkItemEvent>());
            }

            var assignedToMember = request.Team.SingleOrDefault(member => !resolutionUpdate[WorkItemAssignedToField].IsEmpty() &&
                                                                !string.IsNullOrEmpty(resolutionUpdate[WorkItemAssignedToField].OldValue) &&
                                                                resolutionUpdate[WorkItemAssignedToField].OldValue.Contains(member.Email));

            if (assignedToMember == null)
            {
                assignedToMember = request.Team.SingleOrDefault(t => (!string.IsNullOrEmpty(request.WorkItem[WorkItemAssignedToField]) && request.WorkItem[WorkItemAssignedToField].Contains(t.Email)));
            }

            var resolvedByMemeber = request.Team.SingleOrDefault(member => resolutionUpdate.Fields.ContainsKey(WorkItemResolvedByField) && resolutionUpdate[WorkItemResolvedByField].NewValue.Contains(member.Email));

            if (assignedToMember != null)
            {
                resolvedByMemeber = assignedToMember;
            }

            var resolvedDate = DateTime.Parse(resolutionUpdate[WorkItemChangedDateField].NewValue);
            var resolvedBy   = new UserReference {
                Email = resolvedByMemeber.Email, Title = resolvedByMemeber.DisplayName
            };

            return(new[]
            {
                new WorkItemResolvedEvent(GetWorkItemWrapper(request.WorkItem), resolvedDate, resolvedBy)
            });
        }
        public void ShouldReturnNoneResolution(WorkItemResolutionRequest request)
        {
            var result = _classifier.Classify(request);

            result.Should().NotBeNull();
            result.IsNone.Should().BeTrue();
        }
Ejemplo n.º 3
0
        public WorkItemResolution Classify(WorkItemResolutionRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var workItem = request.WorkItem;

            if (workItem == null || workItem.Updates == null || !workItem.Updates.Any())
            {
                return(WorkItemResolution.None);
            }

            if (!_supportedTypes.Contains(workItem.WorkItemType))
            {
                return(WorkItemResolution.None);
            }
            try
            {
                return(ClassifyInternal(request));
            }
            catch (Exception ex)
            {
                return(WorkItemResolution.GetError(ex));
            }
        }
Ejemplo n.º 4
0
        protected override IEnumerable <IWorkItemEvent> ClassifyInternal(WorkItemResolutionRequest request)
        {
            _requestProcessor?.Invoke(request);

            return(new[] { new DummyWorkItemEvent(GetWorkItemWrapper(request.WorkItem), DateTime.UtcNow.AddDays(-1), new UserReference {
                    Email = string.Empty, Title = string.Empty
                }) });
        }
Ejemplo n.º 5
0
        protected override WorkItemResolution ClassifyInternal(WorkItemResolutionRequest request)
        {
            if (_requestProcessor != null)
            {
                _requestProcessor(request);
            }

            return(new WorkItemResolution(request.WorkItem, _resolution, "Because", DateTime.UtcNow.AddDays(-1), string.Empty, string.Empty));
        }
        private bool WasResolvedByTeamMember(WorkItemUpdateViewModel update, WorkItemResolutionRequest request)
        {
            var assignedTo = update[WorkItemAssignedToField].IsEmpty() ? request.WorkItem[WorkItemAssignedToField] : update[WorkItemAssignedToField].OldValue;
            var resolvedBy = update[WorkItemResolvedByField].NewValue;

            return(update[WorkItemStateField].NewValue == WorkItemStateResolved &&
                   update[WorkItemStateField].OldValue != WorkItemStateClosed &&
                   request.Team.Any(t => (!string.IsNullOrEmpty(assignedTo) && assignedTo.Contains(t.Email)) || (!string.IsNullOrEmpty(resolvedBy) && resolvedBy.Contains(t.Email))));
        }
        public void ShouldReturnClosedResolution(WorkItemResolutionRequest request, DateTime expectedResolutionDate, TeamMember expectedTeamMember)
        {
            var result = _classifier.Classify(request);

            result.Should().NotBeNull();
            result.Resolution.Should().Be("Closed");
            result.Reason.Should().Be("Fixed");
            result.ResolutionDate.Should().BeCloseTo(expectedResolutionDate, 1000);
            result.MemberEmail.Should().Be(expectedTeamMember.Email);
            result.MemberName.Should().Be(expectedTeamMember.DisplayName);
        }
Ejemplo n.º 8
0
        public void ShouldReturnResolvedResolution(WorkItemResolutionRequest request, string expectedReason, DateTime expectedResolutionDate, TeamMemberViewModel expectedTeamMember)
        {
            var result = _classifier.Classify(request);

            result.Should().NotBeNull();
            var resolution = result.Single();

            resolution.Should().BeOfType <WorkItemResolvedEvent>();
            resolution.Date.Should().BeCloseTo(expectedResolutionDate, precision: 1000);
            resolution.AssociatedUser.Email.Should().Be(expectedTeamMember.Email);
            resolution.AssociatedUser.Title.Should().Be(expectedTeamMember.DisplayName);
        }
Ejemplo n.º 9
0
        protected override IEnumerable <IWorkItemEvent> ClassifyInternal(WorkItemResolutionRequest request)
        {
            var wrapper = GetWorkItemWrapper(request.WorkItem);
            var updates = wrapper.Updates;

            var reOpens = updates.Where(u => (IsResolved(u.State.Old) || IsClosed(u.State.Old)) && (IsActive(u.State.New) || IsNew(u.State.New)));

            foreach (var reOpen in reOpens)
            {
                // TODO: Consider using update id instead of relying on reference equality
                var previousUpdates = updates.TakeWhile(u => u != reOpen);
                var resolvedUpdate  = previousUpdates.LastOrDefault(u => IsResolved(u.State.New));
                if (resolvedUpdate is null)
                {
                    resolvedUpdate = previousUpdates.LastOrDefault(u => IsClosed(u.State.New));
                }

                if (resolvedUpdate is null)
                {
                    _logger.LogWarning("Encountered ReOpenEvent without corresponding Resolved or Closed update while classifying {WorkItem}.", wrapper.Id);
                    continue;
                }

                var associatedUser = IsOnTheTeam(resolvedUpdate.AssignedTo.Old, request.Team) ? resolvedUpdate.AssignedTo.Old : null;
                if (associatedUser is null)
                {
                    if (IsResolved(resolvedUpdate.State.New))
                    {
                        associatedUser = IsOnTheTeam(resolvedUpdate.ResolvedBy.New, request.Team) ? resolvedUpdate.ResolvedBy.New : null;
                    }
                    else if (IsClosed(resolvedUpdate.State.New))
                    {
                        associatedUser = IsOnTheTeam(resolvedUpdate.ClosedBy.New, request.Team) ? resolvedUpdate.ClosedBy.New : null;
                    }
                }

                if (associatedUser is null)
                {
                    _logger.LogInformation("Reopen detected for Work item '{WorkItem}' but it was resolved not by team member.", wrapper.Id);
                    continue;
                }

                yield return(new WorkItemReOpenedEvent(wrapper, reOpen.ChangedDate.New, associatedUser));
            }
        }
        public void PassCorrectClassificationRequest()
        {
            WorkItemResolutionRequest request = null;
            var c   = new DummyClassifier(DummyResolution1, requestProcessor: r => request = r);
            var ctx = new WorkItemClassificationContext(new[] { c });

            var workitem  = GetWorkitem(DummyClassifier.SupportedType);
            var startDate = DateTime.UtcNow.AddDays(-7);
            var endDate   = DateTime.UtcNow.AddDays(-2);

            ctx.Classify(workitem, new ClassificationScope(_teamMembers, startDate, endDate));

            request.Should().NotBeNull();
            request.Team.Should().BeEquivalentTo(_teamMembers);
            request.WorkItem.Should().Be(workitem);
            request.StartDate.Should().Be(startDate);
            request.EndDate.Should().Be(endDate);
        }
Ejemplo n.º 11
0
        protected override WorkItemResolution ClassifyInternal(WorkItemResolutionRequest request)
        {
            var resolutionUpdate = request.WorkItem.Updates.LastOrDefault(u => WasClosedByTeamMember(u, request.Team));
            var wasEverResolved  = request.WorkItem.Updates.Any(u => u.State.NewValue == WorkItemStates.Resolved);

            if (resolutionUpdate == null || wasEverResolved)
            {
                return(WorkItemResolution.None);
            }

            var reason           = resolutionUpdate.Reason.NewValue;
            var assignedToMember = request.Team.SingleOrDefault(m => !resolutionUpdate.AssignedTo.IsEmpty &&
                                                                !string.IsNullOrEmpty(resolutionUpdate.AssignedTo.OldValue) &&
                                                                resolutionUpdate.AssignedTo.OldValue.Contains(m.Email));
            var closedByMemeber = request.Team.Single(m => resolutionUpdate.ClosedBy.NewValue.Contains(m.Email));

            if (assignedToMember != null)
            {
                closedByMemeber = assignedToMember;
            }

            return(new WorkItemResolution(request.WorkItem, WorkItemStates.Closed, reason, resolutionUpdate.ChangedDate, closedByMemeber.Email, closedByMemeber.DisplayName));
        }
Ejemplo n.º 12
0
        protected override IEnumerable <IWorkItemEvent> ClassifyInternal(WorkItemResolutionRequest request)
        {
            var resolutionUpdate = request.WorkItem.Updates.LastOrDefault(u => WasClosedByTeamMember(u, request));
            var wasEverResolved  = request.WorkItem.Updates.Any(u => u[WorkItemStateField].NewValue == WorkItemStateResolved);

            if (resolutionUpdate == null || wasEverResolved)
            {
                return(Enumerable.Empty <IWorkItemEvent>());
            }

            var reason           = resolutionUpdate[WorkItemReasonField].NewValue;
            var assignedToMember = request.Team.SingleOrDefault(m => !resolutionUpdate[WorkItemAssignedToField].IsEmpty() &&
                                                                !string.IsNullOrEmpty(resolutionUpdate[WorkItemAssignedToField].OldValue) &&
                                                                resolutionUpdate[WorkItemAssignedToField].OldValue.Contains(m.Email));

            if (assignedToMember == null)
            {
                assignedToMember = request.Team.SingleOrDefault(t => (!string.IsNullOrEmpty(request.WorkItem[WorkItemAssignedToField]) && request.WorkItem[WorkItemAssignedToField].Contains(t.Email)));
            }

            var closedByMemeber = request.Team.SingleOrDefault(m => resolutionUpdate[WorkItemClosedByField].NewValue.Contains(m.Email));

            if (assignedToMember != null)
            {
                closedByMemeber = assignedToMember;
            }

            var closedDate = DateTime.Parse(resolutionUpdate[WorkItemChangedDateField].NewValue);
            var closedBy   = new UserReference {
                Email = closedByMemeber.Email, Title = closedByMemeber.DisplayName
            };

            return(new[]
            {
                new WorkItemClosedEvent(new VstsWorkItem(request.WorkItem), closedDate, closedBy)
            });
        }
Ejemplo n.º 13
0
 protected abstract WorkItemResolution ClassifyInternal(WorkItemResolutionRequest request);
Ejemplo n.º 14
0
 public WorkItemResolution Classify(WorkItemResolutionRequest request)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 15
0
 protected override WorkItemResolution ClassifyInternal(WorkItemResolutionRequest request)
 {
     throw new Exception(ExpectedReason);
 }
Ejemplo n.º 16
0
        public void ShouldReturnNoneResolution(WorkItemResolutionRequest request)
        {
            var result = _classifier.Classify(request);

            result.Should().BeEmpty();
        }
Ejemplo n.º 17
0
 protected override IEnumerable <IWorkItemEvent> ClassifyInternal(WorkItemResolutionRequest request)
 {
     throw new Exception(ExpectedReason);
 }
Ejemplo n.º 18
0
 private bool IsValidResolutionRequest(WorkItemResolutionRequest request)
 {
     return(request.WorkItem != null && request.Team != null && request.Team.Count() == ActualMembersCount);
 }