public async void Should_Output_ReleaseNote()
    {
        // Given
        var options = new ReleaseOptions {
            MileStone = "v1.0.0", Owner = "root", Repository = "test"
        };
        var dbContext = EnsureDbCreated(options);
        var service   = new ReleaseService(dbContext, FakeConsole);

        // When
        var result = await service.Execute(options, new Mock <IGitHubClient>().Object);

        // Then
        Assert.Equal(0, result);
        Assert.Single(FakeConsole.Messages);
        Assert.Equal(
            @"As part of this release we had 3 issues closed.
The highest priority among them is ""high"".

### Bug
* Found a bug! #1
* Another bug #2

### Enhancement
* Some improvement on build #3

",
            FakeConsole.Messages[0],
            ignoreLineEndingDifferences: true);

        Assert.Empty(FakeConsole.WarnMessages);
        Assert.Empty(FakeConsole.ErrorMessages);
    }
    public async void PullRequest_Already_Exists()
    {
        // Given
        var options = new ReleaseOptions {
            CreatePullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test"
        };
        var dbContext       = EnsureDbCreated(options);
        var service         = new ReleaseService(dbContext, FakeConsole);
        var gitbucketClient = new Mock <IGitHubClient>();

        gitbucketClient
        .Setup(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>()))
        .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>
        {
            new FakePullRequest(new FakeGitReference("develop"), new FakeGitReference("master"))
        }));

        // When
        var result = await service.Execute(options, gitbucketClient.Object);

        // Then
        Assert.Equal(1, result);
        Assert.Empty(FakeConsole.Messages);
        Assert.Single(FakeConsole.WarnMessages);
        Assert.Equal("A pull request already exists for root:develop.", FakeConsole.WarnMessages[0]);
        Assert.Empty(FakeConsole.ErrorMessages);
    }
    public async void Milestone_Has_Issue_Without_Labels()
    {
        // Given
        var options = new ReleaseOptions {
            MileStone = "v1.0.0", Owner = "root", Repository = "test"
        };
        var dbContextOptions = new DbContextOptionsBuilder <GitBucketDbContext>()
                               .UseInMemoryDatabase(databaseName: "Milestone_Has_Issue_Without_Labels")
                               .Options;

        var dbContext = new GitBucketDbContext(dbContextOptions);

        dbContext.Issues.Add(new Core.Models.Issue
        {
            Milestone = new Core.Models.Milestone
            {
                RepositoryName = options.Repository,
                Title          = options.MileStone,
                UserName       = options.Owner,
            },
            RepositoryName = options.Repository,
            UserName       = options.Owner,
            OpenedUserName = "******",
            Title          = "Implement xxx feature",
        });

        dbContext.SaveChanges();

        var service = new ReleaseService(dbContext, FakeConsole);

        // When
        var result = await service.Execute(options, new Mock <IGitHubClient>().Object);

        // Then
        Assert.Equal(1, result);
        Assert.Single(FakeConsole.Messages);
        Assert.Equal("", FakeConsole.Messages[0]);

        Assert.Equal(3, FakeConsole.WarnMessages.Count);
        Assert.Equal("There are unclosed issues in \"v1.0.0\".", FakeConsole.WarnMessages[0]);
        Assert.Equal("Do you want to continue?([Y]es/[N]o): yes", FakeConsole.WarnMessages[1]);
        Assert.Equal("There are issues which have no labels in \"v1.0.0\".", FakeConsole.WarnMessages[2]);

        Assert.Empty(FakeConsole.ErrorMessages);
    }
    public async void Milestone_Has_No_PullRequest()
    {
        // Given
        var dbContextOptions = new DbContextOptionsBuilder <GitBucketDbContext>()
                               .UseInMemoryDatabase(databaseName: "Milestone_Has_No_PullRequest")
                               .Options;

        var dbContext = new GitBucketDbContext(dbContextOptions);
        var options   = new ReleaseOptions {
            FromPullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test"
        };
        var service = new ReleaseService(dbContext, FakeConsole);

        // When
        var result = await service.Execute(options, new Mock <IGitHubClient>().Object);

        // Then
        Assert.Equal(1, result);
        Assert.Empty(FakeConsole.Messages);
        Assert.Single(FakeConsole.WarnMessages);
        Assert.Empty(FakeConsole.ErrorMessages);
        Assert.Equal("There are no pull requests related to \"v1.0.0\".", FakeConsole.WarnMessages[0]);
    }
    public async void Should_Create_PullRequest_With_Different_Options()
    {
        // Given
        var options = new ReleaseOptions
        {
            Base = "release/v1.0.0",
            CreatePullRequest = true,
            FromPullRequest   = true,
            Head       = "master2",
            MileStone  = "v1.0.0",
            Owner      = "root",
            Repository = "test",
            Title      = "Amazing PR",
        };

        var dbContext       = EnsureDbCreated(options);
        var service         = new ReleaseService(dbContext, FakeConsole);
        var gitbucketClient = new Mock <IGitHubClient>();

        gitbucketClient
        .SetupSequence(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>()))
        .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>
        {
            new FakePullRequest(new FakeGitReference("improve-performance"), new FakeGitReference("master"))
        }))
        .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>
        {
            new FakePullRequest(new FakeGitReference("improve-performance"), new FakeGitReference("master")),
            new FakePullRequest(new FakeGitReference("release/v1.0.0"), new FakeGitReference("master"), 2)
        }));

        var body = string.Empty;

        gitbucketClient
        .Setup(g => g.PullRequest.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <NewPullRequest>()))
        .Callback((string owner, string name, NewPullRequest newPullRequest) => body = newPullRequest.Body)
        .ThrowsAsync(new InvalidCastException("Ignore InvalidCastException because of escaped response."));

        gitbucketClient.Setup(g => g.Issue.Labels.AddToIssue(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <string[]>()));

        // When
        var result = await service.Execute(options, gitbucketClient.Object);

        // Then
        Assert.Equal(0, result);

        gitbucketClient
        .Verify(g => g.PullRequest.Create(
                    It.Is <string>(o => o == "root"),
                    It.Is <string>(r => r == "test"),
                    It.Is <NewPullRequest>(p =>
                                           p.Title == "Amazing PR" &&
                                           p.Head == "master2" &&
                                           p.Base == "release/v1.0.0")));

        Assert.Equal(@"As part of this release we had 1 pull requests closed.
The highest priority among them is ""default"".

### Bug
* Fix a bug #4

",
                     body,
                     ignoreLineEndingDifferences: true);

        Assert.Single(FakeConsole.Messages);
        Assert.Equal("A new pull request has been successfully created!", FakeConsole.Messages[0]);
        Assert.Empty(FakeConsole.WarnMessages);
        Assert.Empty(FakeConsole.ErrorMessages);
    }
    public async void Should_Create_Draft_PullRequest()
    {
        // Given
        var options = new ReleaseOptions {
            Draft = true, CreatePullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test"
        };
        var dbContext = EnsureDbCreated(options);

        dbContext.PullRequests.AddRange(new List <Core.Models.PullRequest>
        {
            new Core.Models.PullRequest {
                UserName = "******", RepositoryName = "test", RequestBranch = "develop", Branch = "master", IssueId = 1, CommitIdFrom = "test", CommitIdTo = "test", RequestRepositoryName = "test", RequestUserName = "******"
            },
            new Core.Models.PullRequest {
                UserName = "******", RepositoryName = "test", RequestBranch = "develop", Branch = "master", IssueId = 2, CommitIdFrom = "test", CommitIdTo = "test", RequestRepositoryName = "test", RequestUserName = "******"
            },
        });
        dbContext.SaveChanges();

        var service         = new ReleaseService(dbContext, FakeConsole);
        var gitbucketClient = new Mock <IGitHubClient>();

        gitbucketClient
        .SetupSequence(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>()))
        .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>()))
        .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>
        {
            new FakePullRequest(new FakeGitReference("develop"), new FakeGitReference("master"), 2)
        }));

        var  body    = string.Empty;
        bool?isDraft = null;

        gitbucketClient
        .Setup(g => g.PullRequest.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <NewPullRequest>()))
        .Callback((string owner, string name, NewPullRequest newPullRequest) =>
        {
            body    = newPullRequest.Body;
            isDraft = newPullRequest.Draft;
        })
        .ThrowsAsync(new InvalidCastException("Ignore InvalidCastException because of escaped response."));

        gitbucketClient.Setup(g => g.Issue.Labels.AddToIssue(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <string[]>()));

        // When
        var result = await service.Execute(options, gitbucketClient.Object);

        // Then
        Assert.Equal(0, result);

        gitbucketClient
        .Verify(g => g.PullRequest.Create(
                    It.Is <string>(o => o == "root"),
                    It.Is <string>(r => r == "test"),
                    It.Is <NewPullRequest>(p =>
                                           p.Title == "v1.0.0" &&
                                           p.Head == "develop" &&
                                           p.Base == "master")));

        Assert.Equal(@"As part of this release we had 3 issues closed.
The highest priority among them is ""high"".

### Bug
* Found a bug! #1
* Another bug #2

### Enhancement
* Some improvement on build #3

",
                     body,
                     ignoreLineEndingDifferences: true);

        Assert.Single(FakeConsole.Messages);
        Assert.Equal("A new pull request has been successfully created!", FakeConsole.Messages[0]);
        Assert.Empty(FakeConsole.WarnMessages);
        Assert.Empty(FakeConsole.ErrorMessages);
        Assert.True(isDraft);
    }