public async Task UpdateWorkItems(Account account, CancellationToken cancellationToken) { var workItems = await this.GetWorkItems(account, cancellationToken); foreach (var workItem in workItems) { try { var html = HttpUtility.HtmlDecode(workItem.Fields.DescriptionHtml); if (!string.IsNullOrWhiteSpace(html)) { var content = new[] { new Op { op = AddOperation, path = DescriptionField, value = html } }.ToJson(); using (var stringContent = new CapturedStringContent(content, JsonPatchMediaType)) { var pat = account.IsPat ? this.GetBase64Token(account.Token) : (BearerAuthHeaderPrefix + account.Token); await $"https://dev.azure.com/{account.Org}/{account.Project}/_apis/wit/workitems/{workItem.Id}?api-version=6.0" .WithHeader(AuthHeader, pat) .PatchAsync(stringContent); ColorConsole.Write(workItem.Id.ToString(), ".".Blue()); } } } catch (Exception ex) { await this.LogError(ex, workItem.Id.ToString()); } } ColorConsole.WriteLine(); }
public static async Task <bool> SaveWorkItemsAsync(WorkItem workItem) { var pat = GetBase64Token(Token); var ops = new[] { new Op { op = "add", path = "/fields/Microsoft.VSTS.Scheduling.CompletedWork", value = workItem.Fields.CompletedWork }, new Op { op = "add", path = "/fields/Microsoft.VSTS.Scheduling.RemainingWork", value = workItem.Fields.RemainingWork } }.ToList(); var content = new CapturedStringContent(ops?.ToJson(), "application/json-patch+json"); try { var result = await string.Format(CultureInfo.InvariantCulture, WorkItemUpdateUrl, workItem.Id) .WithHeader(AuthHeader, pat) .PatchAsync(content) .ConfigureAwait(false); var success = result.StatusCode == (int)System.Net.HttpStatusCode.OK; return(success); } catch (Exception ex) { Log.Error(ex, "Unable to save Work-item"); return(false); } }
/// <summary>Sends an asynchronous POST request.</summary> /// <param name="request">The IFlurlRequest instance.</param> /// <param name="data">Data to parse.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <param name="completionOption">The HttpCompletionOption used in the request. Optional.</param> /// <returns>A Task whose result is the response body as a Stream.</returns> public static Task <Stream> PostStringStreamAsync( this IFlurlRequest request, string data, CancellationToken cancellationToken = default, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) { using var capturedStringContent = new CapturedStringContent(data); return(request.SendAsync(HttpMethod.Post, capturedStringContent, cancellationToken, completionOption).ReceiveStream()); }
/// <summary> /// Update Test Run. /// </summary> /// <param name="testRun">Test Run details.</param> /// <param name="testRunId">Test Run Id.</param> /// <returns>Task.</returns> public static async Task UpdateTestRunAsync(TestRun testRun, string testRunId) { using (var content = new CapturedStringContent(new { state = Constants.Completed, completedDate = testRun.Times.finish.ToString(), comment = "This Test Run has been created using an Automated Custom Utility." }.ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var updateTestRun = await string.Format(CultureInfo.InvariantCulture, TestRunUrl, testRunId) .WithHeader(AuthorizationHeader, Pat) .PatchAsync(content) .ConfigureAwait(false); } }
/// <summary> /// Update Test Results of a Test Run. /// </summary> /// <param name="testRunId">Test Run Id.</param> /// <param name="resultArray">Test Results Data.</param> /// <returns>Task.</returns> public static async Task UpdateTestResultsOfATestRunAsync(string testRunId, List <object> resultArray) { using (var content = new CapturedStringContent(resultArray.ToArray().ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var result = await string.Format(CultureInfo.InvariantCulture, TestResultsUrl, testRunId) .WithHeader(AuthorizationHeader, Pat) .PatchAsync(content) .ConfigureAwait(false); } }
// chain off an existing FlurlClient: public static async Task <HttpResponseMessage> FlurlClient PostXmlAsync(this FlurlClient fc, string xml) { try { var content = new CapturedStringContent(xml, Encoding.UTF8, "application/xml"); return(await fc.HttpClient.PostAsync(fc.Url, content)); } finally { if (AutoDispose) { Dispose(); } } }
/// <summary> /// Add Attachment to a Test Run. /// </summary> /// <param name="testRunId">Test Run Id.</param> /// <param name="file">Attachment.</param> /// <param name="testRunIds">Test Run Ids in which Attachment should be part of.</param> /// <returns>Task.</returns> public static async Task AddAttachmentToTestRunAsync(string testRunId, string file, List <string> testRunIds) { var bytes = File.ReadAllBytes(file); var stream = Convert.ToBase64String(bytes); using (var content = new CapturedStringContent(new { stream, fileName = file.Split('\\').Last(), attachmentType = "GeneralAttachment", comment = $"This file contains Test Results of following Test Runs - {string.Join(", ", testRunIds)}" }.ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var result = await string.Format(CultureInfo.InvariantCulture, TestRunAttachmentsUrl, testRunId) .WithHeader(AuthorizationHeader, Pat) .PostAsync(content) .ConfigureAwait(false); } }
/// <summary> /// Create new Test Run. /// </summary> /// <param name="testRun">Test Run details.</param> /// <param name="testPlanId">Test Plan Id.</param> /// <param name="testPointIds">Test Point Ids.</param> /// <param name="isAutomated">Automated??</param> /// <returns>New Test Run Object.</returns> public static async Task <JObject> CreateNewTestRunAsync(TestRun testRun, int testPlanId, string[] testPointIds, bool isAutomated = true) { dynamic result; using (var content = new CapturedStringContent(new { testRun.name, automated = isAutomated, plan = new { id = testPlanId }, pointIds = testPointIds, startDate = testRun.Times.start }.ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var testrun = await TestRunsUrl.WithHeader(AuthorizationHeader, Pat) .PostAsync(content) .ConfigureAwait(false); result = testrun.Content.ReadAsJsonAsync <JObject>().Result; } return(result); }
/// <summary> /// Get Test Points by Test Case Ids. /// </summary> /// <param name="testCasesIds">Test Case Ids.</param> /// <returns>List of Test Points.</returns> public static async Task <JObject> GetTestPointsByTestCaseIdsAsync(IEnumerable <string> testCasesIds) { dynamic result; using (var content = new CapturedStringContent(new { PointsFilter = new { TestcaseIds = testCasesIds.ToArray() } }.ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var testpoints = await TestPointsUrl.WithHeader(AuthorizationHeader, Pat) .PostAsync(content) .ConfigureAwait(false); result = testpoints.Content.ReadAsJsonAsync <JObject>().Result; } return(result); }
/// <summary> /// Get WorkItems with Automated Test Name. /// </summary> /// <param name="automatedTestName">Automated Test Name.</param> /// <returns>List of WorkItems.</returns> public static async Task <JObject> GetWorkItemsWithAutomatedTestNameAsAsync(string automatedTestName) { dynamic result; var getWorkItemsWithAutomatedTestNameAs = "Select id From WorkItems Where [System.WorkItemType] = 'Test Case' AND [State] <> 'Closed' AND [State] <> 'Removed' AND [Microsoft.VSTS.TCM.AutomatedTestName]='{0}'"; using (var content = new CapturedStringContent(new { query = string.Format(CultureInfo.InvariantCulture, getWorkItemsWithAutomatedTestNameAs, automatedTestName) }.ToJson(), Encoding.UTF8, JsonBatchHttpRequestMediaType)) { var workTems = await WiqlUrl.WithHeader(AuthorizationHeader, Pat) .PostAsync(content) .ConfigureAwait(false); result = workTems.Content.ReadAsJsonAsync <JObject>().Result; } return(result); }
private static async Task <T> ProcessRequest <T>(string path, string content = null, bool patch = false) { try { // https://www.visualstudio.com/en-us/docs/integrate/api/wit/samples Trace.TraceInformation($"BaseAddress: {Account} | Path: {path} | Content: {content}"); HttpResponseMessage queryHttpResponseMessage; var request = path.WithHeader(AuthHeader, BasicAuth + Pat); if (string.IsNullOrWhiteSpace(content)) { queryHttpResponseMessage = (await request.GetAsync().ConfigureAwait(false)).ResponseMessage; } else { if (patch) { var stringContent = new CapturedStringContent(content, JsonPatchMediaType); queryHttpResponseMessage = (await request.PatchAsync(stringContent).ConfigureAwait(false)).ResponseMessage; } else { var stringContent = new StringContent(content, Encoding.UTF8, JsonMediaType); queryHttpResponseMessage = (await request.PostAsync(stringContent).ConfigureAwait(false)).ResponseMessage; } } if (queryHttpResponseMessage.IsSuccessStatusCode) { var result = await queryHttpResponseMessage.Content.ReadAsStringAsync(); return(JsonConvert.DeserializeObject <T>(result)); } else { throw new Exception($"{queryHttpResponseMessage.ReasonPhrase}"); } } catch (Exception ex) { var err = await ex.ToFullStringAsync().ConfigureAwait(false); WriteError(err); return(default(T)); } }
/// <summary> /// Sends an asynchronous POST request that contains an XML string. /// </summary> /// <param name="client">The IFlurlClient instance.</param> /// <param name="data">Contents of the request body.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation. Optional.</param> /// <param name="completionOption">The HttpCompletionOption used in the request. Optional.</param> /// <returns>A Task whose result is the received HttpResponseMessage.</returns> public static Task <HttpResponseMessage> PostXmlStringAsync(this IFlurlClient client, string data, CancellationToken cancellationToken = default(CancellationToken), HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) { var content = new CapturedStringContent(data, Encoding.UTF8, "text/xml"); return(client.SendAsync(HttpMethod.Post, content: content, cancellationToken: cancellationToken, completionOption: completionOption)); }