Ejemplo n.º 1
0
        public async Task DoNotFetchMorePullRequestsIfCreatedAfterIsSet()
        {
            var page1 = new[] { CreatePR("PR 1", daysAgo: 1), CreatePR("PR 2 skip", daysAgo: 1) };
            var page2 = new[] { CreatePR("PR 3 skip", daysAgo: 3), CreatePR("PR 4", daysAgo: 5) };
            var page3 = new[] { CreatePR("PR 5", daysAgo: 6) };

            SetupPagedGetCollectionOf <PullRequest>()
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page1
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page2
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page3
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = Enumerable.Empty <PullRequest>()
            });

            var query = new PullRequestQuery {
                CreatedAfter = DateTime.UtcNow.AddDays(-4)
            };
            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            result.Should().HaveCount(3);
            _httpClientMock.Verify(c => c.ExecuteGet <CollectionResponse <PullRequest> >(It.IsAny <string>(), _cancellationToken), Times.Exactly(2));
        }
Ejemplo n.º 2
0
        public async Task StopRequestingIfFoundOlderPRsThanRequested()
        {
            var page1 = new[] { CreatePR(daysAgo: 1), CreatePR(daysAgo: 2) };
            var page2 = new[] { CreatePR(daysAgo: 3), CreatePR(daysAgo: 5) };
            var page3 = new[] { CreatePR(daysAgo: 6) };

            SetupPagedGetCollectionOf <PullRequest>()
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page1
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page2
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page3
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = Enumerable.Empty <PullRequest>()
            });
            var query = new PullRequestQuery {
                CreatedAfter = DateTime.UtcNow.AddDays(-4)
            };

            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            VerifyPagedRequests <PullRequest>(Times.Exactly(2));

            result.Should().HaveCount(3);
            result.Should().BeEquivalentTo(page1.Union(page2.Take(1)));
        }
Ejemplo n.º 3
0
        private void FetchPullrequestsForRepository(List <PullRequest> resultingPrs, string repositoryName, string projectName)
        {
            var sw        = Stopwatch.StartNew();
            var totalTime = TimeSpan.FromMilliseconds(0);

            Parallel.ForEach(Input.Members, member =>
            {
                _progressReporter.Report($"Looking for {member.DisplayName} pull requests in {projectName}/{repositoryName}");
                var pullRequestsQuery = PullRequestQuery.New(Input.Query.StartDate)
                                        .WithFilter(IsPullRequestMatch)
                                        .WithParameter("creatorId", member.Id.ToString())
                                        .WithParameter("status", "all");
                var pullRequests = _vstsRepository.GetPullRequests(projectName, repositoryName, pullRequestsQuery)
                                   .GetAwaiter()
                                   .GetResult();
                _logger.LogInformation("Fetched pull requests for '{Member}'. Time: {OperationTime}", member.Email, sw.Elapsed);
                totalTime += sw.Elapsed;
                sw.Restart();

                _progressReporter.Report($"Found {pullRequests.Count()} pull requests from {member.DisplayName} in {projectName}/{repositoryName}.", GetProgressStep());
                lock (_locker)
                {
                    resultingPrs.AddRange(pullRequests);
                }
            });
            sw.Stop();
            _logger.LogInformation("Finished fetching pull requests for '{Repository}'. Time: {OperationTime}", repositoryName, totalTime);
        }
Ejemplo n.º 4
0
        public async Task CorrectlySetSkipCountWithQuery()
        {
            var page1 = new[] { CreatePR("PR 1"), CreatePR("PR 2 skip") };
            var page2 = new[] { CreatePR("PR 3 skip"), CreatePR("PR 4") };
            var page3 = new[] { CreatePR("PR 5") };

            int skipTotal = 0;

            SetupPagedGetCollectionOf <PullRequest>(u => ValidateUrlWithPaging(u, ref skipTotal))
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page1
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page2
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = page3
            })
            .ReturnsAsync(new CollectionResponse <PullRequest> {
                Value = Enumerable.Empty <PullRequest>()
            });

            var query = new PullRequestQuery {
                CustomFilter = p => !p.Title.Contains("skip")
            };
            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            result.Should().HaveCount(3);
            skipTotal.Should().Be(11);
        }
Ejemplo n.º 5
0
        private async Task <IEnumerable <PullRequest> > GetPullRequests(VSTSRepository repositoryInfo, VSTSProject project)
        {
            var query = PullRequestQuery.New(Input.Query.StartDate)
                        .WithFilter(p => p.CreationDate >= Input.Query.StartDate && p.CreationDate <= Input.Query.EndDate)
                        .WithParameter("status", "all");

            return(await _vstsRepository.GetPullRequests(project.Name, repositoryInfo.Name, query));
        }
Ejemplo n.º 6
0
        private bool ValidateUrlWithQuery(string url, PullRequestQuery query)
        {
            var uri         = new Uri(url);
            var queryString = uri.Query;

            return(queryString.Contains($"searchCriteria.status={query.Status}") &&
                   queryString.Contains($"searchCriteria.reviewerId={query.ReviewerId}") &&
                   queryString.Contains($"searchCriteria.creatorId={query.CreatorId}"));
        }
Ejemplo n.º 7
0
        public async Task ShouldNotThrowIfErrorRetrievingPullRequests()
        {
            _clientMock.Setup(c => c.ExecuteGet <PullRequestsResponse>(It.IsAny <string>()))
            .Returns(Task.FromResult((PullRequestsResponse)null));

            var result = await _repository.GetPullRequests("Foo", "Bar", PullRequestQuery.New(DateTime.UtcNow));

            result.Should().NotBeNull();
            result.Should().BeEmpty();
        }
Ejemplo n.º 8
0
        private void FetchPullrequests()
        {
            var isDisabled = _repository.GetFieldValue <Settings, bool>(_ => true, s => s.PullRequestsSettings.DisablePullRequestsJob);

            if (isDisabled)
            {
                _logger.LogWarning("Pull requests job is disabled in settings.");
                return;
            }

            var teamMembers  = GetTeamMembers();
            var profiles     = _repository.GetAll <Profile>();
            var repositories = _repository.GetAll <VSTSRepository>();
            var projects     = _repository.GetAll <VSTSProject>();

            foreach (var teamMember in teamMembers)
            {
                var memberRepositoriesAndProjects = profiles.Where(p => p.Members.Contains(teamMember.Id))
                                                    .SelectMany(p => p.Repositories)
                                                    .Select(r =>
                {
                    var repository = repositories.Single(ar => ar.Id == r);
                    var project    = projects.Single(p => p.Id == repository.Project);
                    return(repository, project);
                });

                var retrievedPullRequests = new List <PullRequest>();
                foreach (var repositoryAndProject in memberRepositoriesAndProjects)
                {
                    var query = PullRequestQuery.New(teamMember.LastPullRequestsFetchDate)
                                .WithFilter(IsPullRequestMatch)
                                .WithParameter("creatorId", teamMember.Id.ToString())
                                .WithParameter("status", "all");

                    var pullRequests = _vstsClient.GetPullRequests(repositoryAndProject.project.Name, repositoryAndProject.repository.Name, query)
                                       .GetAwaiter()
                                       .GetResult();
                    retrievedPullRequests.AddRange(pullRequests);
                }

                if (teamMember.PullRequests == null)
                {
                    teamMember.PullRequests = Enumerable.Empty <PullRequest>();
                }

                var newPullrequests = retrievedPullRequests.Except(teamMember.PullRequests);
                _logger.LogInformation("Found {newPullRequestsNumber} pullrequests for '{TeamMember}'", newPullrequests.Count(), teamMember.Email);
                teamMember.PullRequests = teamMember.PullRequests.Union(newPullrequests);
                teamMember.LastPullRequestsFetchDate = DateTime.UtcNow;

                _repository.CreateOrUpdateAsync(teamMember)
                .GetAwaiter()
                .GetResult();
            }
        }
Ejemplo n.º 9
0
        public async Task <BacklogResponse <PullRequest[]> > GetPullRequestsAsync(PullRequestQuery query = null)
        {
            query = query ?? new PullRequestQuery();

            var client   = Project.Client;
            var response = await client.GetAsync($"/api/v2/projects/{Project.Id}/git/repositories/{Id}/pullRequests", query.Build()).ConfigureAwait(false);

            return(await client.CreateResponseAsync <PullRequest[], List <_PullRequest> >(
                       response,
                       HttpStatusCode.OK,
                       data => data.Select(x => new PullRequest(x, this)).ToArray()).ConfigureAwait(false));
        }
Ejemplo n.º 10
0
        public async Task <BacklogResponse <int> > GetPullRequestCountAsync(PullRequestQuery query = null)
        {
            query = query ?? new PullRequestQuery();

            var client   = Project.Client;
            var response = await client.GetAsync($"/api/v2/projects/{Project.Id}/git/repositories/{Id}/pullRequests/count", query.Build()).ConfigureAwait(false);

            return(await client.CreateResponseAsync <int, _Count>(
                       response,
                       HttpStatusCode.OK,
                       data => data.count).ConfigureAwait(false));
        }
Ejemplo n.º 11
0
        public async Task FilterByDate()
        {
            var pullRequests = new[] { CreatePR(daysAgo: 5), CreatePR(daysAgo: 3), CreatePR(daysAgo: 2) };

            SetupOnePageOf(pullRequests);
            var query = new PullRequestQuery {
                CreatedAfter = DateTime.UtcNow.AddDays(-4)
            };

            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            result.Should().HaveCount(2);
            result.Should().BeEquivalentTo(pullRequests.Skip(1));
        }
Ejemplo n.º 12
0
        public async Task CustomFilter()
        {
            var pullRequests = new[] { CreatePR("Bug 1"), CreatePR("Task 1"), CreatePR("Bug 2") };

            SetupOnePageOf(pullRequests);
            var query = new PullRequestQuery {
                CustomFilter = p => p.Title.StartsWith("Bug")
            };

            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            result.Should().HaveCount(2);
            result.Should().OnlyContain(p => query.CustomFilter(p));
        }
Ejemplo n.º 13
0
        public async Task CustomFilterWithDateFilter()
        {
            var pullRequests = new[] { CreatePR("Bug 1", daysAgo: 2), CreatePR("Task 1", daysAgo: 2), CreatePR("Bug 2", daysAgo: 4) };

            SetupOnePageOf(pullRequests);
            var query = new PullRequestQuery {
                CustomFilter = p => p.Title.StartsWith("Bug"), CreatedAfter = DateTime.UtcNow.AddDays(-3)
            };

            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            result.Should().HaveCount(1);
            result.Should().BeEquivalentTo(pullRequests.Take(1));
        }
Ejemplo n.º 14
0
        public async Task IncludesQueryParametersInUrl()
        {
            var query = new PullRequestQuery
            {
                CreatorId    = Guid.NewGuid(),
                ReviewerId   = Guid.NewGuid(),
                Status       = "Active",
                CreatedAfter = DateTime.UtcNow.AddDays(-3)
            };
            var pullRequests = new[] { CreatePR(daysAgo: 2), CreatePR(daysAgo: 1) };

            SetupOnePageOf(pullRequests, s => ValidateUrlWithQuery(s, query));

            var result = await _client.GetPullRequestsAsync(ProjectName, RepositoryName, query, _cancellationToken);

            _httpClientMock.VerifyAll();

            result.Should().NotBeNull();
            result.Should().NotBeEmpty();
            result.Should().BeEquivalentTo(pullRequests);
        }
Ejemplo n.º 15
0
        /// <inheritdoc />
        public async Task <IEnumerable <PullRequest> > GetPullRequestsAsync(string project, string repository, PullRequestQuery query, CancellationToken cancellationToken = default(CancellationToken))
        {
            ThrowIfArgumentNullOrEmpty(project, nameof(project));
            ThrowIfArgumentNullOrEmpty(repository, nameof(repository));

            if (query == null)
            {
                query = PullRequestQuery.None;
            }

            var haveMorePullRequests = true;
            var skip            = 0;
            var allPullRequests = new List <PullRequest>();

            while (haveMorePullRequests)
            {
                var url = VstsUrlBuilder.Create(_instanceName)
                          .ForPullRequests(project, repository)
                          .WithQueryParameterIfNotEmpty("searchCriteria.status", query.Status)
                          .WithQueryParameterIfNotEmpty("searchCriteria.reviewerId", query.ReviewerId)
                          .WithQueryParameterIfNotEmpty("searchCriteria.creatorId", query.CreatorId)
                          .WithQueryParameter("$skip", skip)
                          .Build();

                var pullRequestsResponse = await _httpClient.ExecuteGet <CollectionResponse <PullRequest> >(url, cancellationToken);

                var pullRequests = pullRequestsResponse?.Value ?? Enumerable.Empty <PullRequest>();

                haveMorePullRequests = pullRequests.Any() && (!query.CreatedAfter.HasValue || pullRequests.Min(p => p.CreationDate) >= query.CreatedAfter);

                if (query.CreatedAfter.HasValue)
                {
                    pullRequests = pullRequests.Where(p => p.CreationDate >= query.CreatedAfter);
                }

                if (query.CustomFilter != null)
                {
                    pullRequests = pullRequests.Where(query.CustomFilter);
                }

                allPullRequests.AddRange(pullRequests);

                skip = allPullRequests.Count;
            }

            return(allPullRequests);
        }
Ejemplo n.º 16
0
        private async Task FetchPullRequests(string repositoryName, string projectName, List <PullRequest> pullrequests, PullRequestQuery query, int startFrom = 0)
        {
            var sw = Stopwatch.StartNew();
            var pullRequestsUrlBuilder = VSTSApiUrl.Create(_configuration.Value.InstanceName)
                                         .ForPullRequests(projectName, repositoryName);

            foreach (var parameter in query.Parameters)
            {
                pullRequestsUrlBuilder.WithQueryParameter(parameter.Key, parameter.Value);
            }
            pullRequestsUrlBuilder.WithQueryParameter("$skip", startFrom.ToString());
            var pullRequestsUrl = pullRequestsUrlBuilder.Build(ApiVersion);

            _logger.LogInformation($"Attempting to retrieve pull requests from {pullRequestsUrl}");
            var prsResponse = await _client.ExecuteGet <PullRequestsResponse>(pullRequestsUrl);

            if (prsResponse == null)
            {
                _logger.LogWarning("Couldn't fetch pull requests from the server. Url: {APIUrl}", pullRequestsUrl);
                return;
            }
            _logger.LogInformation($"Retrieved {prsResponse.Value.Count()} PRs from '{repositoryName}' repository. Start position {startFrom}. Operation took: {sw.Elapsed}");

            sw.Restart();
            var prs = prsResponse.Value
                      .Where(query.Filter)
                      .ToList();

            sw.Stop();
            _logger.LogInformation($"Filtering PRs by range took {sw.Elapsed}. Count {prs.Count}");
            pullrequests.AddRange(prs);

            if (prs.Any() && prs.Min(p => p.CreationDate) > query.FromDate)
            {
                await FetchPullRequests(repositoryName, projectName, pullrequests, query, startFrom + prs.Count);
            }
        }
Ejemplo n.º 17
0
        public async Task <IEnumerable <PullRequest> > GetPullRequests(string project, string repository, PullRequestQuery query)
        {
            var pullrequests = new List <PullRequest>();

            await FetchPullRequests(repository, project, pullrequests, query);

            return(pullrequests);
        }
 private bool VerifyPullRequestQuery(PullRequestQuery query, IList <TeamMemberViewModel> members)
 {
     return(members.Any(m => m.Id == query.CreatorId) && string.Equals(query.Status, "all"));
 }