public static async Task <IEnumerable <Milestone> > ListMilestones(this GitHubClient s_gitHub, RepositoryConfiguration repo) { MilestonesClient ms = new MilestonesClient(new ApiConnection(s_gitHub.Connection)); WaitForGitHubCapacity(); return((await ms.GetAllForRepository(repo.Owner, repo.Name)).ToList()); }
public static async Task <IEnumerable <Models.Objects.Milestone> > ListMilestonesAsync(this GitHubClient s_gitHub, RepositoryInfo repo) { MilestonesClient ms = new MilestonesClient(new ApiConnection(s_gitHub.Connection)); var milestonesFromOctokit = await ms.GetAllForRepository(repo.Owner, repo.Name); return(milestonesFromOctokit.Select(m => new Models.Objects.Milestone(m))); }
public async Task RequestsCorrectUrl() { var connection = Substitute.For <IApiConnection>(); var client = new MilestonesClient(connection); await client.GetAllForRepository("fake", "repo"); connection.Received().GetAll <Milestone>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Any <Dictionary <string, string> >()); }
public async Task RequestsCorrectUrlWithRepositoryId() { var connection = Substitute.For <IApiConnection>(); var client = new MilestonesClient(connection); await client.GetAllForRepository(1); connection.Received().GetAll <Milestone>(Arg.Is <Uri>(u => u.ToString() == "repositories/1/milestones"), Arg.Any <Dictionary <string, string> >(), Args.ApiOptions); }
public async Task RequestsCorrectUrl() { var connection = Substitute.For<IApiConnection>(); var client = new MilestonesClient(connection); await client.GetAllForRepository("fake", "repo"); connection.Received().GetAll<Milestone>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Any<Dictionary<string, string>>(), Args.ApiOptions); }
public void SendsAppropriateParameters() { var connection = Substitute.For<IApiConnection>(); var client = new MilestonesClient(connection); client.GetAllForRepository("fake", "repo", new MilestoneRequest { SortDirection = SortDirection.Descending }); connection.Received().GetAll<Milestone>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Is<Dictionary<string, string>>(d => d.Count == 3 && d["direction"] == "desc" && d["state"] == "open" && d["sort"] == "due_date"), Args.ApiOptions); }
public void SendsAppropriateParameters() { var connection = Substitute.For <IApiConnection>(); var client = new MilestonesClient(connection); client.GetAllForRepository("fake", "repo", new MilestoneRequest { SortDirection = SortDirection.Descending }); connection.Received().GetAll <Milestone>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Is <Dictionary <string, string> >(d => d.Count == 3 && d["direction"] == "desc" && d["state"] == "open" && d["sort"] == "due_date")); }
public async Task RequestsCorrectUrlWithApiOptions() { var connection = Substitute.For <IApiConnection>(); var client = new MilestonesClient(connection); var options = new ApiOptions { PageCount = 1, PageSize = 1, StartPage = 1 }; await client.GetAllForRepository("fake", "repo", options); connection.Received().GetAll <Milestone>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Any <Dictionary <string, string> >(), options); }
public async Task RequestsCorrectUrlWithApiOptions() { var connection = Substitute.For<IApiConnection>(); var client = new MilestonesClient(connection); var options = new ApiOptions { PageCount = 1, PageSize = 1, StartPage = 1 }; await client.GetAllForRepository("fake", "repo", options); connection.Received().GetAll<Milestone>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones"), Arg.Any<Dictionary<string, string>>(), options); }
public void SendsAppropriateParametersWithApiOptionsWithRepositoryId() { var connection = Substitute.For <IApiConnection>(); var client = new MilestonesClient(connection); var options = new ApiOptions { PageCount = 1, PageSize = 1, StartPage = 1 }; client.GetAllForRepository(1, new MilestoneRequest { SortDirection = SortDirection.Descending }, options); connection.Received().GetAll <Milestone>(Arg.Is <Uri>(u => u.ToString() == "repositories/1/milestones"), Arg.Is <Dictionary <string, string> >(d => d.Count == 3 && d["direction"] == "desc" && d["state"] == "open" && d["sort"] == "due_date"), options); }
// The incoming param values come (ultimately) come from parsing the incoming URL in QueryCountComponent in // count.component.ts. The URLs could include milestones and/or labels. Here, we have to translate the values // to GitHub/Octokit to get the desired result set. There are some quirks that need clarification below... private async Task <IReadOnlyList <Issue> > GetIssuesAsync(string owner, string repository, string milestone, string labels, string excludedMilestone, string excludedLabels) { // First, for milestone. The URL handled by the Angular app might not have a milestone query parameter so it // would look something like this: // https://<host>/count/nuget/home?label=VS1ES // In that case, the angular app will set the milestone to "undefined" before calling this service, which will // receive a URL like: // https://<host>/api/CountByMilestone/nuget/home/undefined/VS1ES // Map "undefined" and null/whitespace to `null` in the Octokit issue request. This tells Octokit "don't // consider milestones in this query." Then Octokit returns issues regardless of their milestone setting - // including issues with _no_ milestone setting. The URL could have "milestone='*'" - the milestone parameter // will pass that value. GitHub/Octokit treats milestone = '*' as "any _set_ milestone." So Octokit would // return all issues that have any milestone setting of any value - as long as the issue has one is set. // However, with '*' it won't return issues that have NO milestone setting. Finally, if the URL includes a // valid milestone (eg "milestone=15.8"), translate that string value into the corresponding milestone ID and // put that in the issue request... if (string.IsNullOrWhiteSpace(milestone) || milestone == "undefined") { milestone = null; } else if (milestone == "any" || milestone == "*") { milestone = "*"; } else if (milestone != "none") { // This throws a KeyNotFoundException if the incoming milestone value doesn't exist in the repo's collection // of milestone values. Catch it in the calling function... var milestonesClient = new MilestonesClient(new ApiConnection(_gitHubClient.Connection)); var milestoneRequest = new MilestoneRequest { State = ItemStateFilter.Open }; var milestones = await milestonesClient.GetAllForRepository(owner, repository, milestoneRequest); var milestonesByName = milestones.ToDictionary(m => m.Title, m => m.Number); milestone = milestonesByName[milestone].ToString(); } var issueRequest = new RepositoryIssueRequest { Milestone = milestone, State = ItemStateFilter.Open, }; // Second, for labels. In GitHub, issues can have zero or more label values, and the incoming URL could specify a // query for multiple values. Those URL values are passed to this function as a string of comma separated values. // No values in the URL results in labels param value of "undefined" (same as above for milestone); A URL value of // "label=test&label=VS1ES" results in "test,VS1ES" --> split those and add each value to the issue request // Labels collection... if (!string.IsNullOrWhiteSpace(labels) && (labels != "undefined")) { var labelvalues = labels.Split(','); foreach (var label in labelvalues) { issueRequest.Labels.Add(label); } } // This could throw an ApiValidationException if the milestone doesn't exist in the repo. // Catch it in the calling function... var allIssues = await _gitHubClient.Issue.GetAllForRepository(owner, repository, issueRequest); var issues = allIssues.Where(i => i.PullRequest == null); // We now need to exclude the milestone if (!string.IsNullOrEmpty(excludedMilestone) && (excludedMilestone != "undefined")) { issues = issues.Where(i => i.Milestone == null || i.Milestone.Title != excludedMilestone); } // We now need to exclude all the issues that have labels that should be excluded if (!string.IsNullOrEmpty(excludedLabels) && (excludedLabels != "undefined")) { var filteredIssues = new List <Issue>(); var excludedLabelValues = excludedLabels.Split(','); foreach (Issue i in issues) { bool skip = false; foreach (Label l in i.Labels) { if (excludedLabelValues.Contains(l.Name)) { skip = true; } } if (!skip) { filteredIssues.Add(i); } } issues = filteredIssues; } return(issues.ToList()); }
public async Task EnsuresNonNullArguments() { var client = new MilestonesClient(Substitute.For <IApiConnection>()); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository(null, "name")); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", "name", (ApiOptions)null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", null, ApiOptions.None)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository(null, "name", ApiOptions.None)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", "name", (MilestoneRequest)null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", null, new MilestoneRequest())); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository(null, "name", new MilestoneRequest())); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", "name", new MilestoneRequest(), null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", "name", null, ApiOptions.None)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository("owner", null, new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.GetAllForRepository(null, "name", new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("owner", "")); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("", "name")); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("owner", "", ApiOptions.None)); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("", "name", ApiOptions.None)); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("owner", "", new MilestoneRequest())); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("", "name", new MilestoneRequest())); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("owner", "", new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync <ArgumentException>(() => client.GetAllForRepository("", "name", new MilestoneRequest(), ApiOptions.None)); }
public async Task EnsuresNonNullArguments() { var client = new MilestonesClient(Substitute.For<IApiConnection>()); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", null)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository(null, "name")); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", "name", (ApiOptions)null)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", null, ApiOptions.None)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository(null, "name", ApiOptions.None)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", "name", (MilestoneRequest)null)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", null, new MilestoneRequest())); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository(null, "name", new MilestoneRequest())); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", "name", new MilestoneRequest(), null)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", "name", null, ApiOptions.None)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository("owner", null, new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForRepository(null, "name", new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("owner", "")); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("", "name")); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("owner", "", ApiOptions.None)); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("", "name", ApiOptions.None)); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("owner", "", new MilestoneRequest())); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("", "name", new MilestoneRequest())); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("owner", "", new MilestoneRequest(), ApiOptions.None)); await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForRepository("", "name", new MilestoneRequest(), ApiOptions.None)); }
public void SendsAppropriateParametersWithApiOptionsWithRepositoryId() { var connection = Substitute.For<IApiConnection>(); var client = new MilestonesClient(connection); var options = new ApiOptions { PageCount = 1, PageSize = 1, StartPage = 1 }; client.GetAllForRepository(1, new MilestoneRequest { SortDirection = SortDirection.Descending }, options); connection.Received().GetAll<Milestone>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/milestones"), Arg.Is<Dictionary<string, string>>(d => d.Count == 3 && d["direction"] == "desc" && d["state"] == "open" && d["sort"] == "due_date"), options); }