diff --git a/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj b/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj
index ce295098..22897588 100644
--- a/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj
+++ b/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj
@@ -14,13 +14,14 @@
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/Source/GitReleaseManager.Cli/Logging/LogConfiguration.cs b/Source/GitReleaseManager.Cli/Logging/LogConfiguration.cs
index b3dd2966..64e358cb 100644
--- a/Source/GitReleaseManager.Cli/Logging/LogConfiguration.cs
+++ b/Source/GitReleaseManager.Cli/Logging/LogConfiguration.cs
@@ -9,7 +9,7 @@ namespace GitReleaseManager.Cli.Logging
using System.Diagnostics;
using System.Text;
using Destructurama;
- using GitReleaseManager.Cli.Options;
+ using GitReleaseManager.Core.Options;
using Octokit;
using Serilog;
using Serilog.Events;
diff --git a/Source/GitReleaseManager.Cli/Program.cs b/Source/GitReleaseManager.Cli/Program.cs
index fb6de33f..922675a9 100644
--- a/Source/GitReleaseManager.Cli/Program.cs
+++ b/Source/GitReleaseManager.Cli/Program.cs
@@ -7,24 +7,25 @@
namespace GitReleaseManager.Cli
{
using System;
- using System.IO;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
- using AutoMapper;
using CommandLine;
using GitReleaseManager.Cli.Logging;
- using GitReleaseManager.Cli.Options;
using GitReleaseManager.Core;
+ using GitReleaseManager.Core.Commands;
using GitReleaseManager.Core.Configuration;
using GitReleaseManager.Core.Helpers;
+ using GitReleaseManager.Core.Options;
+ using GitReleaseManager.Core.Provider;
+ using GitReleaseManager.Core.ReleaseNotes;
+ using Microsoft.Extensions.DependencyInjection;
+ using Octokit;
using Serilog;
public static class Program
{
- private static FileSystem _fileSystem;
- private static IMapper _mapper;
- private static IVcsProvider _vcsProvider;
+ private static IServiceProvider _serviceProvider;
private static async Task Main(string[] args)
{
@@ -32,10 +33,6 @@ private static async Task Main(string[] args)
// we've upgraded to latest Octokit.
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
- _fileSystem = new FileSystem();
-
- _mapper = AutoMapperConfiguration.Configure();
-
try
{
return await Parser.Default.ParseArguments(args)
@@ -43,17 +40,18 @@ private static async Task Main(string[] args)
.WithParsed(CreateFiglet)
.WithParsed(LogOptions)
.WithParsed(ReportUsernamePasswordDeprecation)
+ .WithParsed(RegisterServices)
.MapResult(
- (CreateSubOptions opts) => CreateReleaseAsync(opts),
- (DiscardSubOptions opts) => DiscardReleaseAsync(opts),
- (AddAssetSubOptions opts) => AddAssetsAsync(opts),
- (CloseSubOptions opts) => CloseMilestoneAsync(opts),
- (OpenSubOptions opts) => OpenMilestoneAsync(opts),
- (PublishSubOptions opts) => PublishReleaseAsync(opts),
- (ExportSubOptions opts) => ExportReleasesAsync(opts),
- (InitSubOptions opts) => CreateSampleConfigFileAsync(opts),
- (ShowConfigSubOptions opts) => ShowConfigAsync(opts),
- (LabelSubOptions opts) => CreateLabelsAsync(opts),
+ (CreateSubOptions opts) => ExecuteCommand(opts),
+ (DiscardSubOptions opts) => ExecuteCommand(opts),
+ (AddAssetSubOptions opts) => ExecuteCommand(opts),
+ (CloseSubOptions opts) => ExecuteCommand(opts),
+ (OpenSubOptions opts) => ExecuteCommand(opts),
+ (PublishSubOptions opts) => ExecuteCommand(opts),
+ (ExportSubOptions opts) => ExecuteCommand(opts),
+ (InitSubOptions opts) => ExecuteCommand(opts),
+ (ShowConfigSubOptions opts) => ExecuteCommand(opts),
+ (LabelSubOptions opts) => ExecuteCommand(opts),
errs => Task.FromResult(1)).ConfigureAwait(false);
}
catch (AggregateException ex)
@@ -74,6 +72,53 @@ private static async Task Main(string[] args)
finally
{
Log.CloseAndFlush();
+ DisposeServices();
+ }
+ }
+
+ private static void RegisterServices(BaseVcsOptions options)
+ {
+ var fileSystem = new FileSystem();
+ var logger = Log.ForContext();
+ var mapper = AutoMapperConfiguration.Configure();
+ var configuration = ConfigurationProvider.Provide(options.TargetDirectory ?? Environment.CurrentDirectory, fileSystem);
+
+ var credentials = string.IsNullOrWhiteSpace(options.Token)
+ ? new Credentials(options.UserName, options.Password)
+ : new Credentials(options.Token);
+
+ var gitHubClient = new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = credentials };
+
+ var serviceCollection = new ServiceCollection()
+ .AddSingleton(logger)
+ .AddSingleton(mapper)
+ .AddSingleton(configuration)
+ .AddSingleton(configuration.Export)
+ .AddSingleton, AddAssetsCommand>()
+ .AddSingleton, CloseCommand>()
+ .AddSingleton, CreateCommand>()
+ .AddSingleton, DiscardCommand>()
+ .AddSingleton, ExportCommand>()
+ .AddSingleton, InitCommand>()
+ .AddSingleton, LabelCommand>()
+ .AddSingleton, OpenCommand>()
+ .AddSingleton, PublishCommand>()
+ .AddSingleton, ShowConfigCommand>()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton(gitHubClient)
+ .AddSingleton()
+ .AddSingleton();
+
+ _serviceProvider = serviceCollection.BuildServiceProvider();
+ }
+
+ private static void DisposeServices()
+ {
+ if (_serviceProvider is IDisposable serviceProvider)
+ {
+ serviceProvider.Dispose();
}
}
@@ -145,129 +190,11 @@ private static int GetConsoleWidth()
}
}
- private static async Task CreateReleaseAsync(CreateSubOptions subOptions)
- {
- Log.Information("Creating release...");
- _vcsProvider = GetVcsProvider(subOptions);
-
- Core.Model.Release release;
- if (!string.IsNullOrEmpty(subOptions.Milestone))
- {
- Log.Verbose("Milestone {Milestone} was specified", subOptions.Milestone);
- var releaseName = subOptions.Name;
- if (string.IsNullOrWhiteSpace(releaseName))
- {
- Log.Verbose("No Release Name was specified, using {Milestone}.", subOptions.Milestone);
- releaseName = subOptions.Milestone;
- }
-
- release = await _vcsProvider.CreateReleaseFromMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone, releaseName, subOptions.TargetCommitish, subOptions.AssetPaths, subOptions.Prerelease).ConfigureAwait(false);
- }
- else
- {
- Log.Verbose("No milestone was specified, switching to release creating from input file");
- release = await _vcsProvider.CreateReleaseFromInputFile(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Name, subOptions.InputFilePath, subOptions.TargetCommitish, subOptions.AssetPaths, subOptions.Prerelease).ConfigureAwait(false);
- }
-
- Log.Information("Drafted release is available at:\n{HtmlUrl}", release.HtmlUrl);
- Log.Verbose("Body:\n{Body}", release.Body);
- return 0;
- }
-
- private static async Task DiscardReleaseAsync(DiscardSubOptions subOptions)
+ private static Task ExecuteCommand(TOptions options)
+ where TOptions : BaseSubOptions
{
- Log.Information("Discarding release {Milestone}", subOptions.Milestone);
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.DiscardRelease(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone);
-
- return 0;
- }
-
- private static async Task AddAssetsAsync(AddAssetSubOptions subOptions)
- {
- Log.Information("Uploading assets");
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.AddAssets(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName, subOptions.AssetPaths).ConfigureAwait(false);
-
- return 0;
- }
-
- private static async Task CloseMilestoneAsync(CloseSubOptions subOptions)
- {
- Log.Information("Closing milestone {Milestone}", subOptions.Milestone);
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.CloseMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone).ConfigureAwait(false);
-
- return 0;
- }
-
- private static async Task OpenMilestoneAsync(OpenSubOptions subOptions)
- {
- Log.Information("Opening milestone {Milestone}", subOptions.Milestone);
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.OpenMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone).ConfigureAwait(false);
-
- return 0;
- }
-
- private static async Task PublishReleaseAsync(PublishSubOptions subOptions)
- {
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.PublishRelease(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName).ConfigureAwait(false);
- return 0;
- }
-
- private static async Task ExportReleasesAsync(ExportSubOptions subOptions)
- {
- Log.Information("Exporting release {TagName}", subOptions.TagName);
- _vcsProvider = GetVcsProvider(subOptions);
-
- var releasesMarkdown = await _vcsProvider.ExportReleases(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName).ConfigureAwait(false);
-
- using (var sw = new StreamWriter(File.Open(subOptions.FileOutputPath, FileMode.OpenOrCreate)))
- {
- sw.Write(releasesMarkdown);
- }
-
- return 0;
- }
-
- private static Task CreateSampleConfigFileAsync(InitSubOptions subOptions)
- {
- Log.Information("Creating sample configuration file");
- var directory = subOptions.TargetDirectory ?? Environment.CurrentDirectory;
- ConfigurationProvider.WriteSample(directory, _fileSystem);
- return Task.FromResult(0);
- }
-
- private static Task ShowConfigAsync(ShowConfigSubOptions subOptions)
- {
- var configuration = ConfigurationProvider.GetEffectiveConfigAsString(subOptions.TargetDirectory ?? Environment.CurrentDirectory, _fileSystem);
-
- Log.Information("{Configuration}", configuration);
- return Task.FromResult(0);
- }
-
- private static async Task CreateLabelsAsync(LabelSubOptions subOptions)
- {
- Log.Information("Creating standard labels");
- _vcsProvider = GetVcsProvider(subOptions);
-
- await _vcsProvider.CreateLabels(subOptions.RepositoryOwner, subOptions.RepositoryName).ConfigureAwait(false);
- return 0;
- }
-
- private static IVcsProvider GetVcsProvider(BaseVcsOptions subOptions)
- {
- var configuration = ConfigurationProvider.Provide(subOptions.TargetDirectory ?? Environment.CurrentDirectory, _fileSystem);
-
- Log.Information("Using {Provider} as VCS Provider", "GitHub");
- return new GitHubProvider(_mapper, configuration, subOptions.UserName, subOptions.Password, subOptions.Token);
+ var command = _serviceProvider.GetRequiredService>();
+ return command.Execute(options);
}
private static void LogOptions(BaseSubOptions options)
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/AddAssetsCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/AddAssetsCommandTests.cs
new file mode 100644
index 00000000..f3b0cc62
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/AddAssetsCommandTests.cs
@@ -0,0 +1,54 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class AddAssetsCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private AddAssetsCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new AddAssetsCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new AddAssetSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ TagName = "0.1.0",
+ AssetPaths = new List(),
+ };
+
+ _vcsService.AddAssetsAsync(options.RepositoryOwner, options.RepositoryName, options.TagName, options.AssetPaths).
+ Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).AddAssetsAsync(options.RepositoryOwner, options.RepositoryName, options.TagName, options.AssetPaths).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/CloseCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/CloseCommandTests.cs
new file mode 100644
index 00000000..d8a28f44
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/CloseCommandTests.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class CloseCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private CloseCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new CloseCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new CloseSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ Milestone = "0.1.0",
+ };
+
+ _vcsService.CloseMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone)
+ .Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).CloseMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any(), options.Milestone);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/CreateCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/CreateCommandTests.cs
new file mode 100644
index 00000000..414a2a8d
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/CreateCommandTests.cs
@@ -0,0 +1,91 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Model;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class CreateCommandTests
+ {
+ private readonly Release _release = new Release { Body = "Release Body", HtmlUrl = "Html Url" };
+
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private CreateCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new CreateCommand(_vcsService, _logger);
+ }
+
+ [TestCase(null, 2)]
+ [TestCase("release", 1)]
+ public async Task Should_Create_Release_From_Milestone(string name, int logVerboseCount)
+ {
+ var options = new CreateSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ Milestone = "milestone",
+ Name = name,
+ TargetCommitish = "target commitish",
+ AssetPaths = new List(),
+ Prerelease = false,
+ };
+
+ var releaseName = options.Name ?? options.Milestone;
+
+ _vcsService.CreateReleaseFromMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone, releaseName, options.TargetCommitish, options.AssetPaths, options.Prerelease)
+ .Returns(_release);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).CreateReleaseFromMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone, releaseName, options.TargetCommitish, options.AssetPaths, options.Prerelease).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any());
+ _logger.Received(logVerboseCount).Verbose(Arg.Any(), options.Milestone);
+ _logger.Received(1).Information(Arg.Any(), _release.HtmlUrl);
+ _logger.Received(1).Verbose(Arg.Any(), _release.Body);
+ }
+
+ [Test]
+ public async Task Should_Create_Release_From_InputFile()
+ {
+ var options = new CreateSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ InputFilePath = "file path",
+ TargetCommitish = "target commitish",
+ AssetPaths = new List(),
+ Prerelease = false,
+ };
+
+ _vcsService.CreateReleaseFromInputFileAsync(options.RepositoryOwner, options.RepositoryName, options.Name, options.InputFilePath, options.TargetCommitish, options.AssetPaths, options.Prerelease)
+ .Returns(_release);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).CreateReleaseFromInputFileAsync(options.RepositoryOwner, options.RepositoryName, options.Name, options.InputFilePath, options.TargetCommitish, options.AssetPaths, options.Prerelease).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any());
+ _logger.Received(1).Information(Arg.Any(), _release.HtmlUrl);
+ _logger.Received(1).Verbose(Arg.Any(), _release.Body);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/DiscardCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/DiscardCommandTests.cs
new file mode 100644
index 00000000..c0e0aa88
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/DiscardCommandTests.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class DiscardCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private DiscardCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new DiscardCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new DiscardSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ Milestone = "0.1.0",
+ };
+
+ _vcsService.DiscardReleaseAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone)
+ .Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).DiscardReleaseAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any(), options.Milestone);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/ExportCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/ExportCommandTests.cs
new file mode 100644
index 00000000..fc8988b3
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/ExportCommandTests.cs
@@ -0,0 +1,69 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.IO;
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class ExportCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private ExportCommand _command;
+ private string _fileOutputPath;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new ExportCommand(_vcsService, _logger);
+ _fileOutputPath = Path.Combine(Path.GetTempPath(), "ReleaseExport.txt");
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new ExportSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ TagName = "0.1.0",
+ FileOutputPath = _fileOutputPath,
+ };
+
+ var releaseText = "releaseText";
+
+ _vcsService.ExportReleasesAsync(options.RepositoryOwner, options.RepositoryName, options.TagName)
+ .Returns(releaseText);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ var exportFileExists = File.Exists(_fileOutputPath);
+ exportFileExists.ShouldBeTrue();
+
+ var exportFileContent = File.ReadAllText(_fileOutputPath);
+ exportFileContent.ShouldBe(releaseText);
+
+ await _vcsService.Received(1).ExportReleasesAsync(options.RepositoryOwner, options.RepositoryName, options.TagName).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any(), options.TagName);
+
+ if (exportFileExists)
+ {
+ File.Delete(_fileOutputPath);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/InitCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/InitCommandTests.cs
new file mode 100644
index 00000000..7cf01494
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/InitCommandTests.cs
@@ -0,0 +1,56 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.IO;
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Helpers;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class InitCommandTests
+ {
+ private IFileSystem _fileSystem;
+ private ILogger _logger;
+ private InitCommand _command;
+ private string _targetDirectory;
+
+ [SetUp]
+ public void Setup()
+ {
+ _fileSystem = new FileSystem();
+ _logger = Substitute.For();
+ _command = new InitCommand(_fileSystem, _logger);
+ _targetDirectory = Path.GetTempPath();
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new InitSubOptions { TargetDirectory = _targetDirectory };
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ var configFilePath = Path.Combine(_targetDirectory, "GitReleaseManager.yaml");
+ var configFileExists = File.Exists(configFilePath);
+ configFileExists.ShouldBeTrue();
+
+ _logger.Received(1).Information(Arg.Any());
+
+ if (configFileExists)
+ {
+ File.Delete(configFilePath);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/LabelCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/LabelCommandTests.cs
new file mode 100644
index 00000000..f1f13a4a
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/LabelCommandTests.cs
@@ -0,0 +1,51 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class LabelCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private LabelCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new LabelCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new LabelSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ };
+
+ _vcsService.CreateLabelsAsync(options.RepositoryOwner, options.RepositoryName)
+ .Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).CreateLabelsAsync(options.RepositoryOwner, options.RepositoryName).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/OpenCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/OpenCommandTests.cs
new file mode 100644
index 00000000..c9b660c7
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/OpenCommandTests.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class OpenCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private OpenCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new OpenCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new OpenSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ Milestone = "0.1.0",
+ };
+
+ _vcsService.OpenMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone)
+ .Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).OpenMilestoneAsync(options.RepositoryOwner, options.RepositoryName, options.Milestone).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any(), options.Milestone);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/PublishCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/PublishCommandTests.cs
new file mode 100644
index 00000000..5a585a36
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/PublishCommandTests.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class PublishCommandTests
+ {
+ private IVcsService _vcsService;
+ private ILogger _logger;
+ private PublishCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _vcsService = Substitute.For();
+ _logger = Substitute.For();
+ _command = new PublishCommand(_vcsService, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new PublishSubOptions
+ {
+ RepositoryOwner = "owner",
+ RepositoryName = "repository",
+ TagName = "0.1.0",
+ };
+
+ _vcsService.PublishReleaseAsync(options.RepositoryOwner, options.RepositoryName, options.TagName)
+ .Returns(Task.CompletedTask);
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _vcsService.Received(1).PublishReleaseAsync(options.RepositoryOwner, options.RepositoryName, options.TagName).ConfigureAwait(false);
+ _logger.Received(1).Information(Arg.Any(), options.TagName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Commands/ShowConfigCommandTests.cs b/Source/GitReleaseManager.Core.Tests/Commands/ShowConfigCommandTests.cs
new file mode 100644
index 00000000..dd9bc627
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Commands/ShowConfigCommandTests.cs
@@ -0,0 +1,44 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System.Threading.Tasks;
+using GitReleaseManager.Core.Commands;
+using GitReleaseManager.Core.Helpers;
+using GitReleaseManager.Core.Options;
+using NSubstitute;
+using NUnit.Framework;
+using Serilog;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests.Commands
+{
+ [TestFixture]
+ public class ShowConfigCommandTests
+ {
+ private IFileSystem _fileSystem;
+ private ILogger _logger;
+ private ShowConfigCommand _command;
+
+ [SetUp]
+ public void Setup()
+ {
+ _fileSystem = Substitute.For();
+ _logger = Substitute.For();
+ _command = new ShowConfigCommand(_fileSystem, _logger);
+ }
+
+ [Test]
+ public async Task Should_Execute_Command()
+ {
+ var options = new ShowConfigSubOptions();
+
+ var result = await _command.Execute(options).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ _logger.Received(1).Information(Arg.Any(), Arg.Any());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/EnsureTests.cs b/Source/GitReleaseManager.Core.Tests/EnsureTests.cs
new file mode 100644
index 00000000..87963e90
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/EnsureTests.cs
@@ -0,0 +1,51 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System;
+using System.IO;
+using NUnit.Framework;
+using Shouldly;
+
+namespace GitReleaseManager.Core.Tests
+{
+ [TestFixture]
+ public class EnsureTests
+ {
+ [Test]
+ public void Should_Throw_Exception_When_String_Is_Null()
+ {
+ var paramName = "str";
+
+ var ex = Should.Throw(() => Ensure.IsNotNullOrWhiteSpace(null, paramName));
+ ex.ParamName.ShouldBe(paramName);
+ }
+
+ [TestCase("")]
+ [TestCase(" ")]
+ public void Should_Throw_Exception_When_String_Is_Whitespace(string str)
+ {
+ var paramName = nameof(str);
+
+ var ex = Should.Throw(() => Ensure.IsNotNullOrWhiteSpace(str, paramName));
+ ex.Message.ShouldContain("Value cannot be empty or white-space.");
+ ex.ParamName.ShouldBe(paramName);
+ }
+
+ [Test]
+ public void Should_Throw_Exception_When_File_Not_Exists()
+ {
+ var tempPath = Path.GetTempPath();
+ var tempFile = "TempFile.txt";
+
+ var path = Path.Combine(tempPath, tempFile);
+ var message = "File does not exist";
+
+ var ex = Should.Throw(() => Ensure.FileExists(path, message));
+ ex.Message.ShouldBe(message);
+ ex.FileName.ShouldBe(tempFile);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj b/Source/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj
new file mode 100644
index 00000000..6e29a42c
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj
@@ -0,0 +1,29 @@
+
+
+ 8.0
+ net472;netcoreapp2.2
+ GitReleaseManager.Core.Tests
+ Test Project for GitReleaseManager.Core
+ $(NoWarn);CA1707
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs b/Source/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs
new file mode 100644
index 00000000..fb7cb093
--- /dev/null
+++ b/Source/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs
@@ -0,0 +1,813 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) 2015 - Present - GitTools Contributors
+//
+// -----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading.Tasks;
+using AutoMapper;
+using GitReleaseManager.Core.Provider;
+using NSubstitute;
+using NSubstitute.ExceptionExtensions;
+using NUnit.Framework;
+using Octokit;
+using Shouldly;
+using ApiException = GitReleaseManager.Core.Exceptions.ApiException;
+using Issue = GitReleaseManager.Core.Model.Issue;
+using IssueComment = GitReleaseManager.Core.Model.IssueComment;
+using ItemState = GitReleaseManager.Core.Model.ItemState;
+using ItemStateFilter = GitReleaseManager.Core.Model.ItemStateFilter;
+using Label = GitReleaseManager.Core.Model.Label;
+using Milestone = GitReleaseManager.Core.Model.Milestone;
+using NotFoundException = GitReleaseManager.Core.Exceptions.NotFoundException;
+using RateLimit = GitReleaseManager.Core.Model.RateLimit;
+using Release = GitReleaseManager.Core.Model.Release;
+using ReleaseAssetUpload = GitReleaseManager.Core.Model.ReleaseAssetUpload;
+
+namespace GitReleaseManager.Core.Tests.Provider
+{
+ [TestFixture]
+ public class GitHubProviderTests
+ {
+ private const string _owner = "owner";
+ private const string _repository = "repository";
+ private const string _base = "0.1.0";
+ private const string _head = "0.5.0";
+ private const int _milestoneNumber = 1;
+ private const string _milestoneNumberString = "1";
+ private const string _milestoneTitle = "0.1.0";
+ private const int _issueNumber = 1;
+ private const string _issueComment = "Issue Comment";
+ private const string _labelName = "Label";
+ private const string _tagName = "0.1.0";
+ private const int _releaseId = 1;
+ private const int _assetId = 1;
+ private const string _notFoundMessage = "NotFound";
+
+ private readonly Release _release = new Release();
+ private readonly ReleaseAssetUpload _releaseAssetUpload = new ReleaseAssetUpload();
+ private readonly Octokit.NewLabel _newLabel = new Octokit.NewLabel(_labelName, "ffffff");
+ private readonly Octokit.NewRelease _newRelease = new Octokit.NewRelease(_tagName);
+ private readonly Exception _exception = new Exception("API Error");
+ private readonly Octokit.NotFoundException _notFoundException = new Octokit.NotFoundException(_notFoundMessage, HttpStatusCode.NotFound);
+
+ private IMapper _mapper;
+ private IGitHubClient _gitHubClient;
+ private GitHubProvider _gitHubProvider;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mapper = Substitute.For();
+ _gitHubClient = Substitute.For();
+ _gitHubProvider = new GitHubProvider(_gitHubClient, _mapper);
+ }
+
+ // Assets
+ [Test]
+ public async Task Should_Delete_Asset()
+ {
+ _gitHubClient.Repository.Release.DeleteAsset(_owner, _repository, _assetId)
+ .Returns(Task.FromResult);
+
+ await _gitHubProvider.DeleteAssetAsync(_owner, _repository, _assetId).ConfigureAwait(false);
+
+ await _gitHubClient.Repository.Release.Received(1).DeleteAsset(_owner, _repository, _assetId).ConfigureAwait(false);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Deleting_Asset_For_Non_Existing_Id()
+ {
+ _gitHubClient.Repository.Release.DeleteAsset(_owner, _repository, _assetId)
+ .Returns(Task.FromException(_notFoundException));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.DeleteAssetAsync(_owner, _repository, _assetId)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_notFoundException.Message);
+ ex.InnerException.ShouldBe(_notFoundException);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Deleting_Asset()
+ {
+ _gitHubClient.Repository.Release.DeleteAsset(_owner, _repository, _assetId)
+ .Returns(Task.FromException(_exception));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.DeleteAssetAsync(_owner, _repository, _assetId)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_exception.Message);
+ ex.InnerException.ShouldBe(_exception);
+ }
+
+ [Test]
+ public async Task Should_Upload_Asset()
+ {
+ var octokitRelease = new Octokit.Release();
+ var octokitReleaseAssetUpload = new Octokit.ReleaseAssetUpload();
+
+ _mapper.Map(_release)
+ .Returns(octokitRelease);
+
+ _mapper.Map(_releaseAssetUpload)
+ .Returns(octokitReleaseAssetUpload);
+
+ _gitHubClient.Repository.Release.UploadAsset(octokitRelease, octokitReleaseAssetUpload)
+ .Returns(Task.FromResult(new Octokit.ReleaseAsset()));
+
+ await _gitHubProvider.UploadAssetAsync(_release, _releaseAssetUpload).ConfigureAwait(false);
+
+ _mapper.Received(1).Map(_release);
+ _mapper.Received(1).Map(_releaseAssetUpload);
+ await _gitHubClient.Repository.Release.Received(1).UploadAsset(octokitRelease, octokitReleaseAssetUpload).ConfigureAwait(false);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Uploading_Asset_For_Non_Existing_Release()
+ {
+ _mapper.Map(_release)
+ .Returns(new Octokit.Release());
+
+ _mapper.Map(_releaseAssetUpload)
+ .Returns(new Octokit.ReleaseAssetUpload());
+
+ _gitHubClient.Repository.Release.UploadAsset(Arg.Any(), Arg.Any())
+ .Returns(Task.FromException(_notFoundException));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.UploadAssetAsync(_release, _releaseAssetUpload)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_notFoundException.Message);
+ ex.InnerException.ShouldBe(_notFoundException);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Uploading_Asset()
+ {
+ _mapper.Map(_release)
+ .Returns(new Octokit.Release());
+
+ _mapper.Map(_releaseAssetUpload)
+ .Returns(new Octokit.ReleaseAssetUpload());
+
+ _gitHubClient.Repository.Release.UploadAsset(Arg.Any(), Arg.Any())
+ .Returns(Task.FromException(_exception));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.UploadAssetAsync(_release, _releaseAssetUpload)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_exception.Message);
+ ex.InnerException.ShouldBe(_exception);
+ }
+
+ // Commits
+ [Test]
+ public async Task Should_Get_Commits_Count()
+ {
+ var commitsCount = 12;
+
+ _gitHubClient.Repository.Commit.Compare(_owner, _repository, _base, _head)
+ .Returns(Task.FromResult(new CompareResult(null, null, null, null, null, null, null, null, commitsCount, 0, 0, null, null)));
+
+ var result = await _gitHubProvider.GetCommitsCount(_owner, _repository, _base, _head).ConfigureAwait(false);
+ result.ShouldBe(commitsCount);
+
+ await _gitHubClient.Repository.Commit.Received(1).Compare(_owner, _repository, _base, _head).ConfigureAwait(false);
+ }
+
+ [Test]
+ public async Task Should_Get_Commits_Count_Zero_If_No_Commits_Found()
+ {
+ _gitHubClient.Repository.Commit.Compare(_owner, _repository, _base, _head)
+ .Returns(Task.FromException(_notFoundException));
+
+ var result = await _gitHubProvider.GetCommitsCount(_owner, _repository, _base, _head).ConfigureAwait(false);
+ result.ShouldBe(0);
+
+ await _gitHubClient.Repository.Commit.Received(1).Compare(_owner, _repository, _base, _head).ConfigureAwait(false);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Getting_Commits_Count()
+ {
+ _gitHubClient.Repository.Commit.Compare(_owner, _repository, _base, _head)
+ .Returns(Task.FromException(_exception));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.GetCommitsCount(_owner, _repository, _base, _head)).ConfigureAwait(false);
+ ex.Message.ShouldContain(_exception.Message);
+ ex.InnerException.ShouldBeSameAs(_exception);
+ }
+
+ [TestCase("0.1.0", null, "https://github.com/owner/repository/commits/0.1.0")]
+ [TestCase("0.5.0", "0.1.0", "https://github.com/owner/repository/compare/0.1.0...0.5.0")]
+ public void Should_Get_Commits_Url(string head, string @base, string expectedResult)
+ {
+ var result = _gitHubProvider.GetCommitsUrl(_owner, _repository, head, @base);
+ result.ShouldBe(expectedResult);
+ }
+
+ [TestCaseSource(nameof(GetCommitsUrl_TestCases))]
+ public void Should_Throw_An_Exception_If_Parameter_Is_Invalid(string owner, string repository, string head, string paramName, Type expectedException)
+ {
+ var ex = Should.Throw(() => _gitHubProvider.GetCommitsUrl(owner, repository, head), expectedException);
+ ex.Message.ShouldContain(paramName);
+ }
+
+ public static IEnumerable GetCommitsUrl_TestCases()
+ {
+ var typeArgumentException = typeof(ArgumentException);
+ var typeArgumentNullException = typeof(ArgumentNullException);
+
+ yield return new TestCaseData(null, null, null, "owner", typeArgumentNullException);
+ yield return new TestCaseData("", null, null, "owner", typeArgumentException);
+ yield return new TestCaseData(" ", null, null, "owner", typeArgumentException);
+
+ yield return new TestCaseData("owner", null, null, "repository", typeArgumentNullException);
+ yield return new TestCaseData("owner", "", null, "repository", typeArgumentException);
+ yield return new TestCaseData("owner", " ", null, "repository", typeArgumentException);
+
+ yield return new TestCaseData("owner", "repository", null, "head", typeArgumentNullException);
+ yield return new TestCaseData("owner", "repository", "", "head", typeArgumentException);
+ yield return new TestCaseData("owner", "repository", " ", "head", typeArgumentException);
+ }
+
+ // Issues
+ [Test]
+ public async Task Should_Create_Issue_Comment()
+ {
+ _gitHubClient.Issue.Comment.Create(_owner, _repository, _issueNumber, _issueComment)
+ .Returns(Task.FromResult(new Octokit.IssueComment()));
+
+ await _gitHubProvider.CreateIssueCommentAsync(_owner, _repository, _issueNumber, _issueComment).ConfigureAwait(false);
+
+ await _gitHubClient.Issue.Comment.Received(1).Create(_owner, _repository, _issueNumber, _issueComment).ConfigureAwait(false);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Creating_Issue_Comment_For_Non_Existing_Issue_Number()
+ {
+ _gitHubClient.Issue.Comment.Create(_owner, _repository, _issueNumber, _issueComment)
+ .Returns(Task.FromException(_notFoundException));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.CreateIssueCommentAsync(_owner, _repository, _issueNumber, _issueComment)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_notFoundException.Message);
+ ex.InnerException.ShouldBe(_notFoundException);
+ }
+
+ [Test]
+ public async Task Should_Throw_An_Exception_On_Creating_Issue_Comment()
+ {
+ _gitHubClient.Issue.Comment.Create(_owner, _repository, _issueNumber, _issueComment)
+ .Returns(Task.FromException(_exception));
+
+ var ex = await Should.ThrowAsync(() => _gitHubProvider.CreateIssueCommentAsync(_owner, _repository, _issueNumber, _issueComment)).ConfigureAwait(false);
+ ex.Message.ShouldBe(_exception.Message);
+ ex.InnerException.ShouldBe(_exception);
+ }
+
+ [TestCase(ItemStateFilter.Open)]
+ [TestCase(ItemStateFilter.Closed)]
+ [TestCase(ItemStateFilter.All)]
+ public async Task Should_Get_Issues_For_Milestone(ItemStateFilter itemStateFilter)
+ {
+ var issues = new List();
+
+ _gitHubClient.Issue.GetAllForRepository(_owner, _repository, Arg.Any(), Arg.Any())
+ .Returns(Task.FromResult((IReadOnlyList)new List()));
+
+ _mapper.Map>(Arg.Any