Skip to content

Commit

Permalink
Return work items
Browse files Browse the repository at this point in the history
  • Loading branch information
twenzel committed Sep 27, 2022
1 parent 6766d9d commit 1903650
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
namespace Cake.AzureDevOps.Tests.Fakes
{
using System;
using System.Collections.Generic;
using System.Threading;
using Cake.AzureDevOps.Authentication;
using Microsoft.TeamFoundation.Build.WebApi;
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.VisualStudio.Services.WebApi;
using Moq;

public class FakeAllSetBuildClientFactory : FakeBuildClientFactory
Expand All @@ -29,6 +31,12 @@ public override BuildHttpClient CreateBuildClient(Uri collectionUrl, IAzureDevOp
Project = new TeamProjectReference { Name = projectName },
});

mock.Setup(arg => arg.GetBuildWorkItemsRefsAsync(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int?>(), null, default))
.ReturnsAsync((string projectName, int buildId, int? top, object userState, CancellationToken token) => new List<ResourceRef>
{
new ResourceRef { Id = "42" },
});

mock = this.Setup(mock);

return mock.Object;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Cake.AzureDevOps.Tests.Fakes
{
using System;
using System.Collections.Generic;
using System.Threading;
using Cake.AzureDevOps.Authentication;
using Microsoft.TeamFoundation.TestManagement.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Moq;

public class FakeAllSetWorkItemTrackingClientFactory : FakeWorkItemTrackingClientFactory
{
public override WorkItemTrackingHttpClient CreateWorkItemTrackingClient(Uri collectionUrl, IAzureDevOpsCredentials credentials)
{
var mock = new Mock<WorkItemTrackingHttpClient>(MockBehavior.Strict, collectionUrl, credentials.ToVssCredentials());

mock.Setup(arg => arg.GetWorkItemsAsync(It.IsAny<IEnumerable<int>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<DateTime?>(), It.IsAny<WorkItemExpand?>(), It.IsAny<WorkItemErrorPolicy?>(), null, default))
.ReturnsAsync((IEnumerable<int> workItemIds, IEnumerable<string> fields, DateTime? asOf, WorkItemExpand? expand, WorkItemErrorPolicy? errorPolicy, object userState, CancellationToken token) =>
{
var result = new List<WorkItem>();

foreach (var workItemId in workItemIds)
{
result.Add(new WorkItem { Id = workItemId });
}

return result;
});

mock = this.Setup(mock);

return mock.Object;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Cake.AzureDevOps.Tests.Fakes
{
using System;
using Cake.AzureDevOps.Authentication;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.VisualStudio.Services.Identity;
using Moq;

public abstract class FakeWorkItemTrackingClientFactory : IWorkItemTrackingClientFactory
{
public abstract WorkItemTrackingHttpClient CreateWorkItemTrackingClient(Uri collectionUrl, IAzureDevOpsCredentials credentials);

public WorkItemTrackingHttpClient CreateWorkItemTrackingClient(Uri collectionUrl, IAzureDevOpsCredentials credentials, out Identity authorizedIdentity)
{
authorizedIdentity = new Identity { ProviderDisplayName = "FakeUser", Id = Guid.NewGuid(), IsActive = true };
return this.CreateWorkItemTrackingClient(collectionUrl, credentials);
}

protected virtual Mock<WorkItemTrackingHttpClient> Setup(Mock<WorkItemTrackingHttpClient> m)
{
return m;
}
}
}
39 changes: 34 additions & 5 deletions src/Cake.AzureDevOps.Tests/Pipelines/AzureDevOpsBuildTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public void Should_Return_Empty_List_If_Build_Is_Invalid()
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory);
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = build.GetTestRuns();
Expand All @@ -42,7 +43,8 @@ public void Should_Return_Empty_List_If_Build_Does_Not_Contain_Test_Runs()
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory);
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = build.GetTestRuns();
Expand All @@ -64,7 +66,8 @@ public void Should_Return_List_Of_Test_Runs_With_X_Test_Results_If_X_Is_Less_The
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory);
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = build.GetTestRuns(testRunsCount);
Expand All @@ -87,7 +90,8 @@ public void Should_Throw_If_Input_Test_Outcomes_Are_Invalid()
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory);
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = Record.Exception(() => build.GetTestRuns(null, new string[] { "FakeOutcome" }));
Expand All @@ -105,7 +109,8 @@ public void Should_Return_List_Of_Test_Runs_With_Test_Results()
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory);
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = build.GetTestRuns();
Expand All @@ -126,5 +131,29 @@ public void Should_Return_List_Of_Test_Runs_With_Test_Results()
new AzureDevOpsTestResult { AutomatedTestName = "t3", Outcome = "Passed", ErrorMessage = string.Empty });
}
}

public sealed class TheGetWorkItemsMethod
{
[Fact]
public void Should_Return_List_Of_WorkItems()
{
// Given
var fixture = new BuildFixture(BuildFixture.ValidAzureDevOpsCollectionUrl, "Foo", 42);
var build = new AzureDevOpsBuild(
fixture.Log,
fixture.Settings,
fixture.BuildClientFactory,
fixture.TestManagementClientFactory,
fixture.WorkItemTrackingClientFactory);

// When
var result = build.GetWorkItems();

// Then
result.ShouldNotBeNull();
result.ShouldHaveSingleItem();
result.First().WorkItemId.ShouldBe(42);
}
}
}
}
3 changes: 3 additions & 0 deletions src/Cake.AzureDevOps.Tests/Pipelines/BuildFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ public BuildFixture(string collectionUrl, string projectName, int buildId)

public ITestManagementClientFactory TestManagementClientFactory { get; set; }

public IWorkItemTrackingClientFactory WorkItemTrackingClientFactory { get; set; }

public AzureDevOpsBuildSettings Settings { get; set; }

private void InitialzeFakes()
{
this.Log = new FakeLog();
this.BuildClientFactory = new FakeAllSetBuildClientFactory();
this.TestManagementClientFactory = new FakeAllSetTestManagementClientFactory();
this.WorkItemTrackingClientFactory = new FakeAllSetWorkItemTrackingClientFactory();
}
}
}
63 changes: 56 additions & 7 deletions src/Cake.AzureDevOps/AzureDevOpsAliases.Pipelines.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Cake.AzureDevOps
{
using System.Collections.Generic;
using Cake.AzureDevOps.Boards.WorkItemTracking;
using Cake.AzureDevOps.Pipelines;
using Cake.Core;
using Cake.Core.Annotations;
Expand Down Expand Up @@ -47,7 +48,7 @@ public static AzureDevOpsBuild AzureDevOpsBuild(
context.NotNull(nameof(context));
settings.NotNull(nameof(settings));

var build = new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory());
var build = new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory());

if (build.HasBuildLoaded)
{
Expand Down Expand Up @@ -279,7 +280,7 @@ public static bool AzureDevOpsBuildIsFailing(
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.IsBuildFailing();
}

Expand Down Expand Up @@ -327,7 +328,7 @@ public static IEnumerable<AzureDevOpsChange> AzureDevOpsBuildChanges(
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetChanges();
}

Expand Down Expand Up @@ -375,10 +376,58 @@ public static IEnumerable<int> AzureDevOpsBuildWorkItemIds(
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetWorkItemIds();
}

/// <summary>
/// Gets the work items associated with an Azure Pipelines build.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="settings">Settings for getting the build.</param>
/// <example>
/// <para>Get work items associated with an Azure Pipelines build:</para>
/// <code>
/// <![CDATA[
/// var buildSettings =
/// new AzureDevOpsBuildSettings(
/// new Uri("http://myserver:8080/defaultcollection"),
/// "MyProject",
/// 42,
/// AzureDevOpsAuthenticationNtlm());
///
/// var workItems =
/// AzureDevOpsBuildWorkItems(
/// buildSettings);
///
/// Information("Work item:");
/// foreach (var workItem in workItems)
/// {
/// Information(" {0}: {1}", workItem.Id, workItem.Title);
/// }
/// ]]>
/// </code>
/// </example>
/// <returns>The work item ids associated with the build.
/// Returns an empty list if build could not be found and
/// <see cref="AzureDevOpsBuildSettings.ThrowExceptionIfBuildCouldNotBeFound"/> is set to <c>false</c>.</returns>
/// <exception cref="AzureDevOpsBuildNotFoundException">If build could not be found and
/// <see cref="AzureDevOpsBuildSettings.ThrowExceptionIfBuildCouldNotBeFound"/> is set to <c>true</c>.</exception>
[CakeMethodAlias]
[CakeAliasCategory("Azure Pipelines")]
[CakeNamespaceImport("Cake.AzureDevOps.Pipelines")]
public static IEnumerable<AzureDevOpsWorkItem> AzureDevOpsBuildWorkItems(
this ICakeContext context,
AzureDevOpsBuildSettings settings)
{
context.NotNull(nameof(context));
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetWorkItems();
}

/// <summary>
/// Gets the timeline entries for an Azure Pipelines build.
/// </summary>
Expand Down Expand Up @@ -423,7 +472,7 @@ public static IEnumerable<AzureDevOpsTimelineRecord> AzureDevOpsBuildTimelineRec
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetTimelineRecords();
}

Expand Down Expand Up @@ -471,7 +520,7 @@ public static IEnumerable<AzureDevOpsBuildArtifact> AzureDevOpsBuildArtifacts(
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetArtifacts();
}

Expand Down Expand Up @@ -519,7 +568,7 @@ public static IEnumerable<AzureDevOpsTestRun> AzureDevOpsBuildTestRuns(
settings.NotNull(nameof(settings));

return
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory())
new AzureDevOpsBuild(context.Log, settings, new BuildClientFactory(), new TestManagementClientFactory(), new WorkItemTrackingClientFactory())
.GetTestRuns();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static AzureDevOpsWorkItem AzureDevOpsWorkItem(
/// Make sure the build has the 'Allow Scripts to access OAuth token' option enabled.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="workItemId">ID of the work witem.</param>
/// <param name="workItemId">ID of the work item.</param>
/// <example>
/// <para>Get an Azure DevOps work item:</para>
/// <code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
{
using System;
using System.Collections.Generic;
using System.Linq;
using Cake.AzureDevOps.Authentication;
using Cake.Core.Diagnostics;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
Expand Down Expand Up @@ -36,15 +34,16 @@ public AzureDevOpsWorkItem(ICakeLog log, AzureDevOpsWorkItemSettings settings)
/// <param name="log">The Cake log context.</param>
/// <param name="settings">Settings for accessing AzureDevOps.</param>
/// <param name="workItem">The work item.</param>
internal AzureDevOpsWorkItem(ICakeLog log, AzureDevOpsWorkItemSettings settings, WorkItem workItem)
/// <param name="workItemTrackingClientFactory">A factory to communicate with work item tracking client.</param>
internal AzureDevOpsWorkItem(ICakeLog log, AzureDevOpsWorkItemSettings settings, WorkItem workItem, IWorkItemTrackingClientFactory workItemTrackingClientFactory)
{
log.NotNull(nameof(log));
settings.NotNull(nameof(settings));
workItem.NotNull(nameof(workItem));

this.log = log;
this.workItem = workItem;
this.workItemTrackingClientFactory = new WorkItemTrackingClientFactory();
this.workItemTrackingClientFactory = workItemTrackingClientFactory;
this.settings = settings;
}

Expand Down Expand Up @@ -140,7 +139,7 @@ internal AzureDevOpsWorkItem(
/// <summary>
/// Gets the URL for accessing the web portal of the Azure DevOps collection.
/// </summary>
public Uri CollectionUrl => this.settings.CollectionUrl;
public Uri CollectionUrl => this.settings.CollectionUrl;

/// <summary>
/// Gets the ID of the work item.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System;
using Cake.AzureDevOps.Authentication;
using Cake.AzureDevOps.Pipelines;

/// <summary>
/// Settings for aliases handling work items.
Expand Down Expand Up @@ -81,6 +82,16 @@ public AzureDevOpsWorkItemSettings(int workItemId, IAzureDevOpsCredentials crede
this.WorkItemId = workItemId;
}

/// <summary>
/// Initializes a new instance of the <see cref="AzureDevOpsWorkItemSettings"/> class
/// based on the instance of a <see cref="BaseAzureDevOpsProjectSettings"/> class.
/// </summary>
/// <param name="settings">Settings containing the parameters.</param>
public AzureDevOpsWorkItemSettings(BaseAzureDevOpsProjectSettings settings)
: base(settings)
{
}

/// <summary>
/// Gets the ID of the work item.
/// </summary>
Expand Down
Loading

0 comments on commit 1903650

Please sign in to comment.