static Tuple <PullRequestDetailViewModel, IPullRequestService> CreateTargetAndService(
            string currentBranch    = "master",
            string existingPrBranch = null,
            bool prFromFork         = false,
            bool dirty   = false,
            int aheadBy  = 0,
            int behindBy = 0,
            IPullRequestSessionManager sessionManager = null)
        {
            var repository         = Substitute.For <ILocalRepositoryModel>();
            var currentBranchModel = new BranchModel(currentBranch, repository);

            repository.CurrentBranch.Returns(currentBranchModel);
            repository.CloneUrl.Returns(new UriString(Uri.ToString()));
            repository.LocalPath.Returns(@"C:\projects\ThisRepo");
            repository.Name.Returns("repo");

            var pullRequestService = Substitute.For <IPullRequestService>();

            if (existingPrBranch != null)
            {
                var existingBranchModel = new BranchModel(existingPrBranch, repository);
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Return(existingBranchModel));
            }
            else
            {
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Empty <IBranch>());
            }

            pullRequestService.Checkout(repository, Arg.Any <IPullRequestModel>(), Arg.Any <string>()).Returns(x => Throws("Checkout threw"));
            pullRequestService.GetDefaultLocalBranchName(repository, Arg.Any <int>(), Arg.Any <string>()).Returns(x => Observable.Return($"pr/{x[1]}"));
            pullRequestService.IsPullRequestFromRepository(repository, Arg.Any <IPullRequestModel>()).Returns(!prFromFork);
            pullRequestService.IsWorkingDirectoryClean(repository).Returns(Observable.Return(!dirty));
            pullRequestService.Pull(repository).Returns(x => Throws("Pull threw"));
            pullRequestService.Push(repository).Returns(x => Throws("Push threw"));
            pullRequestService.SwitchToBranch(repository, Arg.Any <IPullRequestModel>())
            .Returns(
                x => Throws("Switch threw"),
                _ => Observable.Return(Unit.Default));

            var divergence = Substitute.For <BranchTrackingDetails>();

            divergence.AheadBy.Returns(aheadBy);
            divergence.BehindBy.Returns(behindBy);
            pullRequestService.CalculateHistoryDivergence(repository, Arg.Any <int>())
            .Returns(Observable.Return(divergence));

            var vm = new PullRequestDetailViewModel(
                pullRequestService,
                sessionManager ?? Substitute.For <IPullRequestSessionManager>(),
                Substitute.For <IModelServiceFactory>(),
                Substitute.For <IUsageTracker>(),
                Substitute.For <IVSGitExt>());

            vm.InitializeAsync(repository, Substitute.For <IConnection>(), "owner", "repo", 1).Wait();

            return(Tuple.Create(vm, pullRequestService));
        }
        static Tuple <PullRequestDetailViewModel, IPullRequestService> CreateTargetAndService(
            string currentBranch    = "master",
            string existingPrBranch = null,
            bool prFromFork         = false,
            bool dirty   = false,
            int aheadBy  = 0,
            int behindBy = 0)
        {
            var repository         = Substitute.For <ILocalRepositoryModel>();
            var currentBranchModel = new BranchModel(currentBranch, repository);

            repository.CurrentBranch.Returns(currentBranchModel);
            repository.CloneUrl.Returns(new UriString(Uri.ToString()));
            repository.LocalPath.Returns(@"C:\projects\ThisRepo");

            var pullRequestService = Substitute.For <IPullRequestService>();

            if (existingPrBranch != null)
            {
                var existingBranchModel = new BranchModel(existingPrBranch, repository);
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Return(existingBranchModel));
            }
            else
            {
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Empty <IBranch>());
            }

            pullRequestService.Checkout(repository, Arg.Any <IPullRequestModel>(), Arg.Any <string>()).Returns(x => Throws("Checkout threw"));
            pullRequestService.GetDefaultLocalBranchName(repository, Arg.Any <int>(), Arg.Any <string>()).Returns(x => Observable.Return($"pr/{x[1]}"));
            pullRequestService.IsPullRequestFromFork(repository, Arg.Any <IPullRequestModel>()).Returns(prFromFork);
            pullRequestService.IsWorkingDirectoryClean(repository).Returns(Observable.Return(!dirty));
            pullRequestService.Pull(repository).Returns(x => Throws("Pull threw"));
            pullRequestService.Push(repository).Returns(x => Throws("Push threw"));
            pullRequestService.SwitchToBranch(repository, Arg.Any <IPullRequestModel>()).Returns(x => Throws("Switch threw"));

            var divergence = Substitute.For <BranchTrackingDetails>();

            divergence.AheadBy.Returns(aheadBy);
            divergence.BehindBy.Returns(behindBy);
            pullRequestService.CalculateHistoryDivergence(repository, Arg.Any <int>())
            .Returns(Observable.Return(divergence));

            var settings = Substitute.For <IPackageSettings>();

            settings.UIState.Returns(new UIState {
                PullRequestDetailState = new PullRequestDetailUIState()
            });

            var vm = new PullRequestDetailViewModel(
                repository,
                Substitute.For <IModelService>(),
                pullRequestService,
                settings,
                Substitute.For <IUsageTracker>());

            return(Tuple.Create(vm, pullRequestService));
        }
        Tuple <PullRequestDetailViewModel, IPullRequestService> CreateTargetAndService(
            string currentBranch    = "master",
            string existingPrBranch = null,
            bool prFromFork         = false,
            bool dirty   = false,
            int aheadBy  = 0,
            int behindBy = 0)
        {
            var repository         = Substitute.For <ILocalRepositoryModel>();
            var currentBranchModel = new BranchModel(currentBranch, repository);

            repository.CurrentBranch.Returns(currentBranchModel);
            repository.CloneUrl.Returns(new UriString(Uri.ToString()));

            var pullRequestService = Substitute.For <IPullRequestService>();

            if (existingPrBranch != null)
            {
                var existingBranchModel = new BranchModel(existingPrBranch, repository);
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Return(existingBranchModel));
            }
            else
            {
                pullRequestService.GetLocalBranches(repository, Arg.Any <IPullRequestModel>())
                .Returns(Observable.Empty <IBranch>());
            }

            pullRequestService.IsPullRequestFromFork(repository, Arg.Any <IPullRequestModel>()).Returns(prFromFork);
            pullRequestService.IsCleanForCheckout(repository).Returns(Observable.Return(!dirty));

            var divergence = Substitute.For <HistoryDivergence>();

            divergence.AheadBy.Returns(aheadBy);
            divergence.BehindBy.Returns(behindBy);
            pullRequestService.CalculateHistoryDivergence(repository, Arg.Any <int>())
            .Returns(Observable.Return(divergence));

            var vm = new PullRequestDetailViewModel(
                repository,
                Substitute.For <IModelService>(),
                pullRequestService);

            return(Tuple.Create(vm, pullRequestService));
        }
        static Tuple <PullRequestDetailViewModel, IPullRequestService> CreateTargetAndService(
            string currentBranch    = "master",
            string existingPrBranch = null,
            bool prFromFork         = false,
            bool dirty   = false,
            int aheadBy  = 0,
            int behindBy = 0,
            IPullRequestSessionManager sessionManager = null)
        {
            var repository = new LocalRepositoryModel
            {
                CloneUrl  = new UriString(Uri.ToString()),
                LocalPath = @"C:\projects\ThisRepo",
                Name      = "repo"
            };

            var currentBranchModel = new BranchModel(currentBranch, repository);
            var gitService         = Substitute.For <IGitService>();

            gitService.GetBranch(repository).Returns(currentBranchModel);

            var pullRequestService = Substitute.For <IPullRequestService>();

            if (existingPrBranch != null)
            {
                var existingBranchModel = new BranchModel(existingPrBranch, repository);
                pullRequestService.GetLocalBranches(repository, Arg.Any <PullRequestDetailModel>())
                .Returns(Observable.Return(existingBranchModel));
            }
            else
            {
                pullRequestService.GetLocalBranches(repository, Arg.Any <PullRequestDetailModel>())
                .Returns(Observable.Empty <BranchModel>());
            }

            pullRequestService.Checkout(repository, Arg.Any <PullRequestDetailModel>(), Arg.Any <string>()).Returns(x => Throws("Checkout threw"));
            pullRequestService.GetDefaultLocalBranchName(repository, Arg.Any <int>(), Arg.Any <string>()).Returns(x => Observable.Return($"pr/{x[1]}"));
            pullRequestService.IsPullRequestFromRepository(repository, Arg.Any <PullRequestDetailModel>()).Returns(!prFromFork);
            pullRequestService.IsWorkingDirectoryClean(repository).Returns(Observable.Return(!dirty));
            pullRequestService.Pull(repository).Returns(x => Throws("Pull threw"));
            pullRequestService.Push(repository).Returns(x => Throws("Push threw"));
            pullRequestService.SwitchToBranch(repository, Arg.Any <PullRequestDetailModel>())
            .Returns(
                x => Throws("Switch threw"),
                _ => Observable.Return(Unit.Default));

            var divergence = Substitute.For <BranchTrackingDetails>();

            divergence.AheadBy.Returns(aheadBy);
            divergence.BehindBy.Returns(behindBy);
            pullRequestService.CalculateHistoryDivergence(repository, Arg.Any <int>())
            .Returns(Observable.Return(divergence));

            if (sessionManager == null)
            {
                var currentSession = Substitute.For <IPullRequestSession>();
                currentSession.PullRequest.Returns(CreatePullRequestModel());
                currentSession.User.Returns(new ActorModel {
                    Login = "******"
                });

                sessionManager = Substitute.For <IPullRequestSessionManager>();
                sessionManager.CurrentSession.Returns(currentSession);
                sessionManager.GetSession("owner", "repo", 1).ReturnsForAnyArgs(currentSession);
            }

            var vm = new PullRequestDetailViewModel(
                pullRequestService,
                sessionManager,
                Substitute.For <IModelServiceFactory>(),
                Substitute.For <IUsageTracker>(),
                Substitute.For <ITeamExplorerContext>(),
                Substitute.For <IPullRequestFilesViewModel>(),
                Substitute.For <ISyncSubmodulesCommand>(),
                Substitute.For <IViewViewModelFactory>(),
                gitService,
                Substitute.For <IOpenIssueishDocumentCommand>(),
                new JoinableTaskContext());

            vm.InitializeAsync(repository, Substitute.For <IConnection>(), "owner", "repo", 1).Wait();

            return(Tuple.Create(vm, pullRequestService));
        }