diff --git a/internal/domain/providers.go b/internal/domain/providers.go index 9739236..d7be557 100644 --- a/internal/domain/providers.go +++ b/internal/domain/providers.go @@ -9,7 +9,7 @@ type RepositoryProvider interface { } type PullRequestProvider interface { - GetPullRequestForBranch(string) (pullRequest *PullRequest, err error) + GetPullRequestForBranch(branch string) (pullRequest *PullRequest, err error) CreatePullRequest(title string, body string, baseBranch string, headBranch string, draft bool, labels []string) (prUrl string, err error) } diff --git a/internal/fakes/domain/fake_branch_provider.go b/internal/fakes/domain/fake_branch_provider.go new file mode 100644 index 0000000..8508388 --- /dev/null +++ b/internal/fakes/domain/fake_branch_provider.go @@ -0,0 +1,29 @@ +package domain + +import ( + "errors" + "fmt" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakeBranchProvider struct{} + +var _ domain.BranchProvider = (*FakeBranchProvider)(nil) + +func NewFakeBranchProvider() FakeBranchProvider { + return FakeBranchProvider{} +} + +func (f *FakeBranchProvider) GetBranchName(issueTracker domain.IssueTracker, issueIdentifier string, repo domain.Repository) (branchName string, err error) { + switch issueTracker.GetIssueTrackerType() { + case domain.IssueTrackerTypeGithub: + return fmt.Sprintf("feature/GH-%s-generated-branch-name", issueIdentifier), nil + case domain.IssueTrackerTypeJira: + return fmt.Sprintf("feature/%s-generated-branch-name", issueIdentifier), nil + default: + + } + + return "", errors.New("unknown issue tracker type") +} diff --git a/internal/fakes/domain/fake_gh_cli.go b/internal/fakes/domain/fake_gh_cli.go new file mode 100644 index 0000000..cbfde68 --- /dev/null +++ b/internal/fakes/domain/fake_gh_cli.go @@ -0,0 +1,15 @@ +package domain + +import "github.com/InditexTech/gh-sherpa/internal/domain" + +type FakeGhCli struct{} + +var _ domain.GhCli = (*FakeGhCli)(nil) + +func NewFakeGhCli() FakeGhCli { + return FakeGhCli{} +} + +func (f FakeGhCli) Execute(result any, args []string) (err error) { + return nil +} diff --git a/internal/fakes/domain/fake_git_provider.go b/internal/fakes/domain/fake_git_provider.go new file mode 100644 index 0000000..e9c1dbb --- /dev/null +++ b/internal/fakes/domain/fake_git_provider.go @@ -0,0 +1,142 @@ +package domain + +import ( + "errors" + "fmt" + "slices" + "strings" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakeGitProvider struct { + RemoteBranches []string + LocalBranches []string + CurrentBranch string + CommitsToPush map[string][]string + BranchWithCommitError []string +} + +var _ domain.GitProvider = (*FakeGitProvider)(nil) + +func NewFakeGitProvider() *FakeGitProvider { + return &FakeGitProvider{ + CurrentBranch: "main", + RemoteBranches: []string{ + "main", + "develop", + }, + LocalBranches: []string{ + "main", + "develop", + }, + CommitsToPush: map[string][]string{}, + BranchWithCommitError: []string{}, + } +} + +func (f *FakeGitProvider) AddLocalBranches(branches ...string) { + f.LocalBranches = append(f.LocalBranches, branches...) +} + +func (f *FakeGitProvider) AddRemoteBranches(branches ...string) { + f.RemoteBranches = append(f.RemoteBranches, branches...) +} + +func (f *FakeGitProvider) BranchExists(branch string) bool { + return slices.Contains(f.LocalBranches, branch) +} + +func (f *FakeGitProvider) FetchBranchFromOrigin(branch string) (err error) { + idx := slices.Index(f.RemoteBranches, branch) + if idx == -1 { + return fmt.Errorf("remote branch %s not found", branch) + } + return nil +} + +func (f *FakeGitProvider) CheckoutNewBranchFromOrigin(branch string, base string) (err error) { + idx := slices.Index(f.RemoteBranches, base) + if idx == -1 { + return fmt.Errorf("remote branch %s not found", base) + } + f.LocalBranches = append(f.LocalBranches, branch) + f.CurrentBranch = branch + return nil +} + +var ErrGetCurrentBranch = errors.New("no current branch") + +func (f *FakeGitProvider) GetCurrentBranch() (branch string, err error) { + if f.CurrentBranch != "" { + return f.CurrentBranch, nil + } + + return "", ErrGetCurrentBranch +} + +func (f *FakeGitProvider) BranchExistsContains(branch string) (name string, exists bool) { + for _, b := range f.LocalBranches { + if strings.Contains(b, branch) { + return b, true + } + } + for _, b := range f.RemoteBranches { + if strings.Contains(b, branch) { + return b, true + } + } + return "", false +} + +func (f *FakeGitProvider) CheckoutBranch(branch string) (err error) { + if !slices.Contains(f.LocalBranches, branch) { + return fmt.Errorf("local branch %s not found", branch) + } + f.CurrentBranch = branch + return nil +} + +var ErrGetCommitsToPush = errors.New("error getting commits to push") + +func (f *FakeGitProvider) GetCommitsToPush(branch string) (commits []string, err error) { + if slices.Contains(f.BranchWithCommitError, branch) { + return commits, ErrGetCommitsToPush + } + + commits, ok := f.CommitsToPush[branch] + if !ok { + commits = []string{} + } + + return commits, nil +} + +func (f *FakeGitProvider) RemoteBranchExists(branch string) (exists bool) { + return slices.Contains(f.RemoteBranches, branch) +} + +func (f *FakeGitProvider) CommitEmpty(message string) (err error) { + currentCommits, ok := f.CommitsToPush[f.CurrentBranch] + if !ok { + currentCommits = []string{} + } + currentCommits = append(currentCommits, message) + f.CommitsToPush[f.CurrentBranch] = currentCommits + return nil +} + +func (f *FakeGitProvider) PushBranch(branch string) (err error) { + if !slices.Contains(f.LocalBranches, branch) { + return fmt.Errorf("local branch %s not found", branch) + } + if slices.Contains(f.RemoteBranches, branch) { + return fmt.Errorf("remote branch %s already exists", branch) + } + f.RemoteBranches = append(f.RemoteBranches, branch) + return nil +} + +func (f *FakeGitProvider) IsCurrentBranch(branch string) bool { + return f.CurrentBranch == branch +} diff --git a/internal/fakes/domain/fake_issue_tracker.go b/internal/fakes/domain/fake_issue_tracker.go new file mode 100644 index 0000000..1cb11ce --- /dev/null +++ b/internal/fakes/domain/fake_issue_tracker.go @@ -0,0 +1,105 @@ +package domain + +import ( + "fmt" + "strings" + + "github.com/InditexTech/gh-sherpa/internal/domain" + "github.com/InditexTech/gh-sherpa/internal/domain/issue_types" +) + +type FakeIssueTracker struct { + IssueTrackerType domain.IssueTrackerType + Configurations map[string]FakeIssueTrackerConfiguration +} + +type FakeIssueTrackerConfiguration struct { + IssueTrackerIdentifier string + IssueType issue_types.IssueType + IssueTypeLabel string + Issue domain.Issue +} + +var _ domain.IssueTracker = (*FakeIssueTracker)(nil) + +func NewFakeIssueTracker() *FakeIssueTracker { + return &FakeIssueTracker{ + Configurations: map[string]FakeIssueTrackerConfiguration{}, + } +} + +func ErrIssueNotInitializedInMap(identifier string) error { + return fmt.Errorf("issue %s not initialized in map", identifier) +} + +func (f *FakeIssueTracker) AddIssue(issueId string, issueType issue_types.IssueType) { + issueTypeLabel := "kind/" + issueType.String() + f.Configurations[issueId] = FakeIssueTrackerConfiguration{ + IssueTrackerIdentifier: f.IssueTrackerType.String(), + IssueType: issueType, + IssueTypeLabel: issueTypeLabel, + Issue: domain.Issue{ + ID: issueId, + IssueTracker: f.IssueTrackerType, + Title: "Sample issue", + Body: "Sample issue body", + Labels: []domain.Label{ + { + Id: issueTypeLabel, + Name: issueTypeLabel, + }, + }, + Url: "https://github.com/InditexTech/gh-sherpa-repo-test/issues/" + issueId, + }, + } +} + +func (f *FakeIssueTracker) GetIssue(issueId string) (issue domain.Issue, err error) { + config, ok := f.Configurations[issueId] + if !ok { + return domain.Issue{}, ErrIssueNotInitializedInMap(issueId) + } + return config.Issue, nil +} + +func (f *FakeIssueTracker) GetIssueType(issue domain.Issue) (issueType issue_types.IssueType) { + return f.Configurations[issue.ID].IssueType +} + +func (f *FakeIssueTracker) GetIssueTypeLabel(issue domain.Issue) string { + return f.Configurations[issue.ID].IssueTypeLabel +} + +func (f *FakeIssueTracker) IdentifyIssue(issueId string) bool { + return f.Configurations[issueId].IssueTrackerIdentifier == string(f.IssueTrackerType) +} + +func (f *FakeIssueTracker) FormatIssueId(issueId string) (formattedIssueId string) { + issueTrackerType := f.GetIssueTrackerType() + if issueTrackerType == domain.IssueTrackerTypeGithub { + return fmt.Sprintf("GH-%s", issueId) + } + + return issueId +} + +func (f *FakeIssueTracker) ParseRawIssueId(identifier string) (issueId string) { + prefix := "" + + switch f.IssueTrackerType { + case domain.IssueTrackerTypeGithub: + prefix = "GH-" + case domain.IssueTrackerTypeJira: + prefix = "PROJECTKEY-" + } + + if strings.HasPrefix(identifier, prefix) { + return strings.ReplaceAll(identifier, prefix, "") + } + + return "" +} + +func (f *FakeIssueTracker) GetIssueTrackerType() domain.IssueTrackerType { + return f.IssueTrackerType +} diff --git a/internal/fakes/domain/fake_issue_tracker_provider.go b/internal/fakes/domain/fake_issue_tracker_provider.go new file mode 100644 index 0000000..5327e2a --- /dev/null +++ b/internal/fakes/domain/fake_issue_tracker_provider.go @@ -0,0 +1,34 @@ +package domain + +import ( + "errors" + "strconv" + "strings" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakeIssueTrackerProvider struct { + IssueTracker domain.IssueTracker +} + +var _ domain.IssueTrackerProvider = (*FakeIssueTrackerProvider)(nil) + +func NewFakeIssueTrackerProvider(issueTracker domain.IssueTracker) *FakeIssueTrackerProvider { + return &FakeIssueTrackerProvider{ + IssueTracker: issueTracker, + } +} + +func (f *FakeIssueTrackerProvider) GetIssueTracker(identifier string) (issueTracker domain.IssueTracker, err error) { + _, err = strconv.Atoi(identifier) + if strings.HasPrefix(identifier, "GH-") || strings.HasPrefix(identifier, "PROJECTKEY-") || err == nil { + return f.IssueTracker, nil + } + + return nil, errors.New("issue tracker not found") +} + +func (f *FakeIssueTrackerProvider) ParseIssueId(identifier string) (issueId string) { + return strings.TrimPrefix(identifier, "GH-") +} diff --git a/internal/fakes/domain/fake_pull_request_provider.go b/internal/fakes/domain/fake_pull_request_provider.go new file mode 100644 index 0000000..c0c6efd --- /dev/null +++ b/internal/fakes/domain/fake_pull_request_provider.go @@ -0,0 +1,78 @@ +package domain + +import ( + "errors" + "fmt" + "slices" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakePullRequestProvider struct { + PullRequests map[string]*domain.PullRequest + PullRequestsWithErrors []string +} + +var _ domain.PullRequestProvider = (*FakePullRequestProvider)(nil) + +func NewFakePullRequestProvider() *FakePullRequestProvider { + return &FakePullRequestProvider{ + PullRequests: map[string]*domain.PullRequest{}, + PullRequestsWithErrors: []string{}, + } +} + +func (f *FakePullRequestProvider) AddPullRequest(branchName string, pr domain.PullRequest) { + f.PullRequests[branchName] = &pr +} + +func (f *FakePullRequestProvider) HasPullRequestForBranch(branch string) bool { + pr := f.PullRequests[branch] + + return pr != nil +} + +func (f *FakePullRequestProvider) GetPullRequestForBranch(branch string) (pullRequest *domain.PullRequest, err error) { + pr := f.PullRequests[branch] + + return pr, nil +} + +func ErrPrAlreadyExists(branch string) error { + return fmt.Errorf("pr already exists for branch %s", branch) +} + +var ErrPullRequestWithError = errors.New("pull request with error") + +func (f *FakePullRequestProvider) CreatePullRequest(title string, body string, baseBranch string, headBranch string, draft bool, labels []string) (prUrl string, err error) { + if slices.Contains(f.PullRequestsWithErrors, headBranch) { + return "", ErrPullRequestWithError + } + + pr := f.PullRequests[headBranch] + if pr != nil && !pr.Closed { + return "", ErrPrAlreadyExists(headBranch) + } + + prLabels := make([]domain.Label, len(labels)) + for i, label := range labels { + prLabels[i] = domain.Label{ + Id: label, + Name: label, + } + } + pr = &domain.PullRequest{ + Title: title, + Number: 5, + State: "OPEN", + Closed: false, + Url: "https://github.com/inditextech/gh-sherpa-test-repo/pulls/5", + HeadRefName: headBranch, + BaseRefName: baseBranch, + Labels: prLabels, + } + + f.PullRequests[headBranch] = pr + + return pr.Url, nil +} diff --git a/internal/fakes/domain/fake_repository_provider.go b/internal/fakes/domain/fake_repository_provider.go new file mode 100644 index 0000000..5b89e5f --- /dev/null +++ b/internal/fakes/domain/fake_repository_provider.go @@ -0,0 +1,33 @@ +package domain + +import ( + "errors" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakeRepositoryProvider struct { + Repository *domain.Repository +} + +var _ domain.RepositoryProvider = (*FakeRepositoryProvider)(nil) + +func NewRepositoryProvider() *FakeRepositoryProvider { + return &FakeRepositoryProvider{ + Repository: &domain.Repository{ + Name: "gh-sherpa-test-repo", + Owner: "inditextech", + NameWithOwner: "inditextech/gh-sherpa-test-repo", + DefaultBranchRef: "main", + }, + } +} + +var ErrRepositoryNotFound = errors.New("repository not found") + +func (f *FakeRepositoryProvider) GetRepository() (repo *domain.Repository, err error) { + if f.Repository != nil { + return f.Repository, nil + } + return nil, ErrRepositoryNotFound +} diff --git a/internal/fakes/domain/fake_user_interaction_provider.go b/internal/fakes/domain/fake_user_interaction_provider.go new file mode 100644 index 0000000..a68fdb6 --- /dev/null +++ b/internal/fakes/domain/fake_user_interaction_provider.go @@ -0,0 +1,29 @@ +package domain + +import ( + "errors" + + "github.com/InditexTech/gh-sherpa/internal/domain" +) + +type FakeUserInteractionProvider struct { + // TODO: Map this :) +} + +var _ domain.UserInteractionProvider = (*FakeUserInteractionProvider)(nil) + +func NewFakeUserInteractionProvider() FakeUserInteractionProvider { + return FakeUserInteractionProvider{} +} + +func (f *FakeUserInteractionProvider) AskUserForConfirmation(msg string, defaultAnswer bool) (answer bool, err error) { + return false, errors.New("not implemented") +} + +func (f *FakeUserInteractionProvider) SelectOrInputPrompt(message string, validValues []string, variable *string, required bool) error { + return errors.New("not implemented") +} + +func (f *FakeUserInteractionProvider) SelectOrInput(name string, validValues []string, variable *string, required bool) error { + return errors.New("not implemented") +} diff --git a/internal/interactive/interactive.go b/internal/interactive/interactive.go index 70da949..2a7f654 100644 --- a/internal/interactive/interactive.go +++ b/internal/interactive/interactive.go @@ -70,6 +70,7 @@ func (u UserInteractionProvider) SelectOrInputPrompt(message string, validValues return handleSurveyError(err) } +// TODO: Do not use "kind/*" here, use the actual config to retriebe the label func GetPromptMessageBranchType(branchType string, issueTrackerType domain.IssueTrackerType) string { if issueTrackerType == domain.IssueTrackerTypeJira { return fmt.Sprintf("Issue type '%s' found. What type of branch name do you want to create?", branchType) diff --git a/internal/use_cases/create_branch_test.go b/internal/use_cases/create_branch_test.go index f5bdb45..a7ac537 100644 --- a/internal/use_cases/create_branch_test.go +++ b/internal/use_cases/create_branch_test.go @@ -1,14 +1,15 @@ package use_cases_test import ( + "fmt" "testing" "github.com/InditexTech/gh-sherpa/internal/domain" "github.com/InditexTech/gh-sherpa/internal/domain/issue_types" + domainFakes "github.com/InditexTech/gh-sherpa/internal/fakes/domain" "github.com/InditexTech/gh-sherpa/internal/mocks" domainMocks "github.com/InditexTech/gh-sherpa/internal/mocks/domain" "github.com/InditexTech/gh-sherpa/internal/use_cases" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" ) @@ -17,34 +18,16 @@ type CreateBranchExecutionTestSuite struct { suite.Suite defaultBranchName string uc use_cases.CreateBranch - gitProvider *domainMocks.MockGitProvider - issueTrackerProvider *domainMocks.MockIssueTrackerProvider - issueTracker *domainMocks.MockIssueTracker + gitProvider *domainFakes.FakeGitProvider + issueTrackerProvider *domainFakes.FakeIssueTrackerProvider + issueTracker *domainFakes.FakeIssueTracker userInteractionProvider *domainMocks.MockUserInteractionProvider branchProvider *domainMocks.MockBranchProvider - repositoryProvider *domainMocks.MockRepositoryProvider + repositoryProvider *domainFakes.FakeRepositoryProvider } -func (s *CreateBranchExecutionTestSuite) expectCreateBranchNotCalled() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutNewBranchFromOrigin) - // s.gitProvider.EXPECT().CheckoutNewBranchFromOrigin(mock.Anything, mock.Anything).Times(0) -} - -func (s *CreateBranchExecutionTestSuite) assertCreateBranchNotCalled() { - s.gitProvider.AssertNotCalled(s.T(), "CheckoutNewBranchFromOrigin") -} - -func (s *CreateBranchExecutionTestSuite) assertCreateBranchCalled(issueTrackerType domain.IssueTrackerType) { - var branchName string - switch issueTrackerType { - case domain.IssueTrackerTypeJira: - branchName = "feature/PROJECTKEY-1-sample-issue" - case domain.IssueTrackerTypeGithub: - fallthrough - default: - branchName = "feature/GH-1-sample-issue" - } - s.gitProvider.AssertCalled(s.T(), "CheckoutNewBranchFromOrigin", branchName, "main") +func (s *CreateBranchExecutionTestSuite) setGetBranchName(branch string) { + s.branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return(branch, nil).Once() } type CreateGithubBranchExecutionTestSuite struct { @@ -60,15 +43,19 @@ func (s *CreateGithubBranchExecutionTestSuite) SetupSuite() { } func (s *CreateGithubBranchExecutionTestSuite) SetupSubTest() { - s.gitProvider = s.initializeGitProvider() - s.issueTrackerProvider = s.initializeIssueTrackerProvider() - s.issueTracker = s.initializeIssueTracker() + s.gitProvider = domainFakes.NewFakeGitProvider() + + s.issueTracker = domainFakes.NewFakeIssueTracker() + s.issueTracker.IssueTrackerType = domain.IssueTrackerTypeGithub + s.issueTracker.AddIssue("1", issue_types.Feature) + s.issueTracker.AddIssue("3", issue_types.Documentation) + s.issueTracker.AddIssue("6", issue_types.Refactoring) + + s.issueTrackerProvider = domainFakes.NewFakeIssueTrackerProvider(s.issueTracker) + s.userInteractionProvider = s.initializeUserInteractionProvider() s.branchProvider = s.initializeBranchProvider() - s.repositoryProvider = s.initializeRepositoryProvider() - - mocks.UnsetExpectedCall(&s.issueTrackerProvider.Mock, s.issueTrackerProvider.GetIssueTracker) - s.issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(s.issueTracker, nil).Maybe() + s.repositoryProvider = domainFakes.NewRepositoryProvider() defaultConfig := use_cases.CreateBranchConfiguration{ FetchFromOrigin: true, @@ -85,54 +72,40 @@ func (s *CreateGithubBranchExecutionTestSuite) SetupSubTest() { } func (s *CreateGithubBranchExecutionTestSuite) TestCreateBranchExecution() { - s.Run("should error if could not get git repository", func() { - mocks.UnsetExpectedCall(&s.repositoryProvider.Mock, s.repositoryProvider.GetRepository) - s.repositoryProvider.EXPECT().GetRepository().Return(nil, assert.AnError).Once() - - s.expectCreateBranchNotCalled() + s.setGetBranchName(s.defaultBranchName) + s.repositoryProvider.Repository = nil s.uc.Cfg.IssueID = "1" err := s.uc.Execute() s.Error(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchNotCalled() + s.False(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if no issue flag is provided", func() { - s.expectCreateBranchNotCalled() - err := s.uc.Execute() s.ErrorContains(err, "sherpa needs an valid issue identifier") - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchNotCalled() + s.False(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if branch already exists with default flag", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/GH-1-sample-issue").Return(true).Maybe() - - s.expectCreateBranchNotCalled() + branchName := "feature/GH-3-local-branch" + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) - s.uc.Cfg.IssueID = "1" + s.uc.Cfg.IssueID = "3" s.uc.Cfg.IsInteractive = false err := s.uc.Execute() - s.ErrorContains(err, "a local branch with the name feature/GH-1-sample-issue already exists") - s.assertCreateBranchNotCalled() + s.ErrorContains(err, fmt.Sprintf("a local branch with the name %s already exists", branchName)) }) s.Run("should create branch if branch doesn't exists with default flag", func() { - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/GH-1-sample-issue").Return(false).Maybe() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutNewBranchFromOrigin) - s.gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/GH-1-sample-issue", "main").Return(nil).Maybe() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" s.uc.Cfg.IsInteractive = false @@ -140,61 +113,37 @@ func (s *CreateGithubBranchExecutionTestSuite) TestCreateBranchExecution() { err := s.uc.Execute() s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchCalled(domain.IssueTrackerTypeGithub) + s.True(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should create branch if not exists without default flag", func() { - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Maybe() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/GH-1-sample-issue").Return(false).Maybe() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" err := s.uc.Execute() s.NoError(err) - s.assertCreateBranchCalled(domain.IssueTrackerTypeGithub) + s.True(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if branch already exists without default flag", func() { - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Maybe() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/GH-1-sample-issue").Return(true).Maybe() - - s.expectCreateBranchNotCalled() + branchName := "feature/GH-3-local-branch" + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) - s.uc.Cfg.IssueID = "1" + s.uc.Cfg.IssueID = "3" err := s.uc.Execute() - s.ErrorContains(err, "a local branch with the name feature/GH-1-sample-issue already exists") - s.assertCreateBranchNotCalled() + s.ErrorContains(err, fmt.Sprintf("a local branch with the name %s already exists", branchName)) }) - -} - -func (s *CreateGithubBranchExecutionTestSuite) initializeGitProvider() *domainMocks.MockGitProvider { - gitProvider := &domainMocks.MockGitProvider{} - - gitProvider.EXPECT().GetCurrentBranch().Return(s.defaultBranchName, nil).Maybe() - gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{}, nil).Maybe() - gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Maybe() - gitProvider.EXPECT().BranchExistsContains("/GH-1-").Return("feature/GH-1-sample-issue", true).Maybe() - gitProvider.EXPECT().BranchExists("/GH-1-").Return(true).Maybe() - - gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().PushBranch(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Maybe() - gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/GH-1-sample-issue", "main").Return(nil).Maybe() - - return gitProvider } func (s *CreateGithubBranchExecutionTestSuite) initializeUserInteractionProvider() *domainMocks.MockUserInteractionProvider { @@ -207,53 +156,12 @@ func (s *CreateGithubBranchExecutionTestSuite) initializeUserInteractionProvider return userInteractionProvider } -func (s *CreateGithubBranchExecutionTestSuite) initializeIssueTrackerProvider() *domainMocks.MockIssueTrackerProvider { - issueTrackerProvider := &domainMocks.MockIssueTrackerProvider{} - - // issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(GetDefaultIssueTracker(), nil).Maybe() - issueTrackerProvider.EXPECT().ParseIssueId(mock.Anything).Return("1").Maybe() - - return issueTrackerProvider -} - func (s *CreateGithubBranchExecutionTestSuite) initializeBranchProvider() *domainMocks.MockBranchProvider { branchProvider := &domainMocks.MockBranchProvider{} - branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return("feature/GH-1-sample-issue", nil).Maybe() - return branchProvider } -func (s *CreateGithubBranchExecutionTestSuite) initializeRepositoryProvider() *domainMocks.MockRepositoryProvider { - repositoryProvider := &domainMocks.MockRepositoryProvider{} - - repositoryProvider.EXPECT().GetRepository().Return(&domain.Repository{ - Owner: "inditex", - Name: "gh-sherpa", - NameWithOwner: "InditexTech/gh-sherpa", - DefaultBranchRef: "main", - }, nil).Maybe() - - return repositoryProvider -} - -func (s *CreateGithubBranchExecutionTestSuite) initializeIssueTracker() *domainMocks.MockIssueTracker { - issueTracker := &domainMocks.MockIssueTracker{} - - issueTracker.EXPECT().FormatIssueId(mock.Anything).Return("GH-1").Maybe() - issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{ - ID: "1", - Title: "Sample issue", - Body: "Sample issue body", - Labels: []domain.Label{}, - IssueTracker: domain.IssueTrackerTypeGithub, - }, nil).Maybe() - issueTracker.EXPECT().GetIssueType(mock.Anything).Return(issue_types.Feature).Maybe() - issueTracker.EXPECT().GetIssueTrackerType().Return(domain.IssueTrackerTypeGithub).Maybe() - - return issueTracker -} - type CreateJiraBranchExecutionTestSuite struct { CreateBranchExecutionTestSuite } @@ -267,15 +175,19 @@ func (s *CreateJiraBranchExecutionTestSuite) SetupSuite() { } func (s *CreateJiraBranchExecutionTestSuite) SetupSubTest() { - s.gitProvider = s.initializeGitProvider() - s.issueTrackerProvider = s.initializeIssueTrackerProvider() - s.issueTracker = s.initializeIssueTracker() + s.gitProvider = domainFakes.NewFakeGitProvider() + + s.issueTracker = domainFakes.NewFakeIssueTracker() + s.issueTracker.IssueTrackerType = domain.IssueTrackerTypeJira + s.issueTracker.AddIssue("PROJECTKEY-1", issue_types.Feature) + s.issueTracker.AddIssue("PROJECTKEY-3", issue_types.Documentation) + s.issueTracker.AddIssue("PROJECTKEY-6", issue_types.Refactoring) + + s.issueTrackerProvider = domainFakes.NewFakeIssueTrackerProvider(s.issueTracker) + s.userInteractionProvider = s.initializeUserInteractionProvider() s.branchProvider = s.initializeBranchProvider() - s.repositoryProvider = s.initializeRepositoryProvider() - - mocks.UnsetExpectedCall(&s.issueTrackerProvider.Mock, s.issueTrackerProvider.GetIssueTracker) - s.issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(s.issueTracker, nil).Maybe() + s.repositoryProvider = domainFakes.NewRepositoryProvider() s.uc = use_cases.CreateBranch{ Git: s.gitProvider, @@ -287,56 +199,42 @@ func (s *CreateJiraBranchExecutionTestSuite) SetupSubTest() { } func (s *CreateJiraBranchExecutionTestSuite) TestCreateBranchExecution() { - issueID := "PROJECTKEY-1" s.Run("should error if could not get git repository", func() { - mocks.UnsetExpectedCall(&s.repositoryProvider.Mock, s.repositoryProvider.GetRepository) - s.repositoryProvider.EXPECT().GetRepository().Return(nil, assert.AnError).Once() - - s.expectCreateBranchNotCalled() + s.setGetBranchName(s.defaultBranchName) + s.repositoryProvider.Repository = nil s.uc.Cfg.IssueID = issueID err := s.uc.Execute() s.Error(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchNotCalled() + s.False(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if no issue flag is provided", func() { - s.expectCreateBranchNotCalled() - err := s.uc.Execute() s.ErrorContains(err, "sherpa needs an valid issue identifier") - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchNotCalled() + s.False(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if branch already exists with default flag", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/PROJECTKEY-1-sample-issue").Return(true).Maybe() - - s.expectCreateBranchNotCalled() + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) - s.uc.Cfg.IssueID = issueID + s.uc.Cfg.IssueID = "PROJECTKEY-3" s.uc.Cfg.IsInteractive = false err := s.uc.Execute() - s.ErrorContains(err, "a local branch with the name feature/PROJECTKEY-1-sample-issue already exists") - s.assertCreateBranchNotCalled() + s.ErrorContains(err, fmt.Sprintf("a local branch with the name %s already exists", branchName)) }) s.Run("should create branch if branch doesn't exists with default flag", func() { - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/PROJECTKEY-1-sample-issue").Return(false).Maybe() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutNewBranchFromOrigin) - s.gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/PROJECTKEY-1-sample-issue", "main").Return(nil).Maybe() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = issueID s.uc.Cfg.IsInteractive = false @@ -344,61 +242,37 @@ func (s *CreateJiraBranchExecutionTestSuite) TestCreateBranchExecution() { err := s.uc.Execute() s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreateBranchCalled(domain.IssueTrackerTypeJira) + s.True(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should create branch if not exists without default flag", func() { - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Maybe() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/PROJECTKEY-1-sample-issue").Return(false).Maybe() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = issueID err := s.uc.Execute() s.NoError(err) - s.assertCreateBranchCalled(domain.IssueTrackerTypeJira) + s.True(s.gitProvider.BranchExists(s.defaultBranchName)) }) s.Run("should error if branch already exists without default flag", func() { - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Maybe() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExists) - s.gitProvider.EXPECT().BranchExists("feature/PROJECTKEY-1-sample-issue").Return(true).Maybe() - - s.expectCreateBranchNotCalled() + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) s.uc.Cfg.IssueID = issueID err := s.uc.Execute() - s.ErrorContains(err, "a local branch with the name feature/PROJECTKEY-1-sample-issue already exists") - s.assertCreateBranchNotCalled() + s.ErrorContains(err, fmt.Sprintf("a local branch with the name %s already exists", branchName)) }) - -} - -func (s *CreateJiraBranchExecutionTestSuite) initializeGitProvider() *domainMocks.MockGitProvider { - gitProvider := &domainMocks.MockGitProvider{} - - gitProvider.EXPECT().GetCurrentBranch().Return(s.defaultBranchName, nil).Maybe() - gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{}, nil).Maybe() - gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Maybe() - gitProvider.EXPECT().BranchExistsContains("/PROJECTKEY-1-").Return("feature/PROJECTKEY-1-sample-issue", true).Maybe() - gitProvider.EXPECT().BranchExists("/PROJECTKEY-1-").Return(true).Maybe() - - gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().PushBranch(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Maybe() - gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/PROJECTKEY-1-sample-issue", "main").Return(nil).Maybe() - - return gitProvider } func (s *CreateJiraBranchExecutionTestSuite) initializeUserInteractionProvider() *domainMocks.MockUserInteractionProvider { @@ -411,54 +285,8 @@ func (s *CreateJiraBranchExecutionTestSuite) initializeUserInteractionProvider() return userInteractionProvider } -func (s *CreateJiraBranchExecutionTestSuite) initializeIssueTrackerProvider() *domainMocks.MockIssueTrackerProvider { - issueTrackerProvider := &domainMocks.MockIssueTrackerProvider{} - - // issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(GetDefaultIssueTracker(), nil).Maybe() - issueTrackerProvider.EXPECT().ParseIssueId(mock.Anything).Return("1").Maybe() - - return issueTrackerProvider -} - -func (s *CreateJiraBranchExecutionTestSuite) initializeRepositoryProvider() *domainMocks.MockRepositoryProvider { - repositoryProvider := &domainMocks.MockRepositoryProvider{} - - repositoryProvider.EXPECT().GetRepository().Return(&domain.Repository{ - Owner: "inditex", - Name: "gh-sherpa", - NameWithOwner: "InditexTech/gh-sherpa", - DefaultBranchRef: "main", - }, nil).Maybe() - - return repositoryProvider -} - -func (s *CreateJiraBranchExecutionTestSuite) initializeIssueTracker() *domainMocks.MockIssueTracker { - issueTracker := &domainMocks.MockIssueTracker{} - - issueTracker.EXPECT().FormatIssueId(mock.Anything).Return("PROJECTKEY-1").Maybe() - issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{ - ID: "1", - Title: "Sample issue", - Body: "Sample issue body", - Labels: []domain.Label{}, - IssueTracker: domain.IssueTrackerTypeJira, - Type: domain.IssueType{ - Id: "3", - Name: "feature", - Description: "A new feature of the product, which has to be developed and tested.", - }, - }, nil).Maybe() - issueTracker.EXPECT().GetIssueType(mock.Anything).Return(issue_types.Feature).Maybe() - issueTracker.EXPECT().GetIssueTrackerType().Return(domain.IssueTrackerTypeJira).Maybe() - - return issueTracker -} - func (s *CreateJiraBranchExecutionTestSuite) initializeBranchProvider() *domainMocks.MockBranchProvider { branchProvider := &domainMocks.MockBranchProvider{} - branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return("feature/PROJECTKEY-1-sample-issue", nil).Maybe() - return branchProvider } diff --git a/internal/use_cases/create_pull_request_test.go b/internal/use_cases/create_pull_request_test.go index 886520a..39822b2 100644 --- a/internal/use_cases/create_pull_request_test.go +++ b/internal/use_cases/create_pull_request_test.go @@ -9,10 +9,10 @@ import ( "github.com/InditexTech/gh-sherpa/internal/config" "github.com/InditexTech/gh-sherpa/internal/domain" "github.com/InditexTech/gh-sherpa/internal/domain/issue_types" + domainFakes "github.com/InditexTech/gh-sherpa/internal/fakes/domain" "github.com/InditexTech/gh-sherpa/internal/mocks" domainMocks "github.com/InditexTech/gh-sherpa/internal/mocks/domain" "github.com/InditexTech/gh-sherpa/internal/use_cases" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" ) @@ -21,20 +21,24 @@ type CreatePullRequestExecutionTestSuite struct { suite.Suite defaultBranchName string uc use_cases.CreatePullRequest - gitProvider *domainMocks.MockGitProvider - issueTrackerProvider *domainMocks.MockIssueTrackerProvider + gitProvider *domainFakes.FakeGitProvider + issueTrackerProvider *domainFakes.FakeIssueTrackerProvider userInteractionProvider *domainMocks.MockUserInteractionProvider - pullRequestProvider *domainMocks.MockPullRequestProvider - issueTracker *domainMocks.MockIssueTracker + pullRequestProvider *domainFakes.FakePullRequestProvider + issueTracker *domainFakes.FakeIssueTracker branchProvider *domainMocks.MockBranchProvider - repositoryProvider *domainMocks.MockRepositoryProvider + repositoryProvider *domainFakes.FakeRepositoryProvider } type CreateGithubPullRequestExecutionTestSuite struct { CreatePullRequestExecutionTestSuite } -func TestCreatePullRequestExecutionTestSuite(t *testing.T) { +func (s *CreatePullRequestExecutionTestSuite) setGetBranchName(branchName string) { + s.branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return(branchName, nil).Once() +} + +func TestCreateGitHubPullRequestExecutionTestSuite(t *testing.T) { suite.Run(t, new(CreateGithubPullRequestExecutionTestSuite)) } @@ -43,16 +47,22 @@ func (s *CreateGithubPullRequestExecutionTestSuite) SetupSuite() { } func (s *CreateGithubPullRequestExecutionTestSuite) SetupSubTest() { - s.gitProvider = s.initializeGitProvider() - s.issueTrackerProvider = s.initializeIssueTrackerProvider() + s.gitProvider = domainFakes.NewFakeGitProvider() + s.gitProvider.AddLocalBranches(s.defaultBranchName) + s.gitProvider.AddRemoteBranches(s.defaultBranchName) + + s.issueTracker = domainFakes.NewFakeIssueTracker() + s.issueTracker.IssueTrackerType = domain.IssueTrackerTypeGithub + s.issueTracker.AddIssue("1", issue_types.Feature) + s.issueTracker.AddIssue("3", issue_types.Documentation) + s.issueTracker.AddIssue("6", issue_types.Refactoring) + + s.issueTrackerProvider = domainFakes.NewFakeIssueTrackerProvider(s.issueTracker) + s.userInteractionProvider = s.initializeUserInteractionProvider() - s.pullRequestProvider = s.initializePullRequestProvider() - s.issueTracker = s.initializeIssueTracker() + s.pullRequestProvider = domainFakes.NewFakePullRequestProvider() s.branchProvider = s.initializeBranchProvider() - s.repositoryProvider = s.initializeRepositoryProvider() - - mocks.UnsetExpectedCall(&s.issueTrackerProvider.Mock, s.issueTrackerProvider.GetIssueTracker) - s.issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(s.issueTracker, nil).Maybe() + s.repositoryProvider = domainFakes.NewRepositoryProvider() defaultConfig := use_cases.CreatePullRequestConfiguration{ IsInteractive: true, @@ -73,191 +83,152 @@ func (s *CreateGithubPullRequestExecutionTestSuite) SetupSubTest() { func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecution() { s.Run("should error if could not get git repository", func() { - mocks.UnsetExpectedCall(&s.repositoryProvider.Mock, s.repositoryProvider.GetRepository) - s.repositoryProvider.EXPECT().GetRepository().Return(nil, assert.AnError).Once() - - s.expectCreatePullRequestNotCalled() + s.repositoryProvider.Repository = nil err := s.uc.Execute() - s.Error(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.ErrorIs(err, domainFakes.ErrRepositoryNotFound) }) s.Run("should error if could not get current branch", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCurrentBranch) - s.gitProvider.EXPECT().GetCurrentBranch().Return("", assert.AnError).Once() - - s.expectCreatePullRequestNotCalled() + s.gitProvider.CurrentBranch = "" err := s.uc.Execute() s.ErrorContains(err, "could not get the current branch name") - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should error if no issue could be identified", func() { branchName := "branch-with-no-issue-name" - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCurrentBranch) - s.gitProvider.EXPECT().GetCurrentBranch().Return(branchName, nil).Once() - - s.expectCreatePullRequestNotCalled() + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) err := s.uc.Execute() expectedError := fmt.Sprintf("could not find an issue identifier in the current branch named %s", branchName) s.EqualError(err, expectedError) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should exit if user does not confirm current branch", func() { + s.gitProvider.CurrentBranch = s.defaultBranchName + s.setGetBranchName(s.defaultBranchName) + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation(mock.Anything, mock.Anything).Return(false, nil).Once() - s.expectCreatePullRequestNotCalled() - err := s.uc.Execute() s.NoError(err) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.defaultBranchName)) }) s.Run("should return error if pr already exists", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - s.expectCreatePullRequestNotCalled() + branchName := "feature/GH-3-pull-request-sample" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.pullRequestProvider.AddPullRequest(branchName, domain.PullRequest{}) + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, "pull request") s.ErrorContains(err, "already exists") - s.assertCreatePullRequestNotCalled() }) s.Run("should not ask the user for branch confirmation if default flag is used", func() { + branchName := "feature/GH-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) s.uc.Cfg.IsInteractive = false - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - err := s.uc.Execute() s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) s.userInteractionProvider.AssertNotCalled(s.T(), "AskUserForConfirmation") }) - s.Run("should create and push empty commit if remote branch nor pull request do not exists", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CommitEmpty) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - s.gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Once() - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - s.pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(mock.Anything, nil).Once() + s.Run("should create and push empty commit if remote branch nor pull request exists", func() { + branchName := "feature/GH-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) err := s.uc.Execute() s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) }) s.Run("should return error if remote branch already exists", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Once() - - s.expectCreatePullRequestNotCalled() + branchName := "feature/GH-1-sample-issue" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists(s.defaultBranchName).Error()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should exit if user does not confirm the commit push when default flag is not used", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCommitsToPush) - s.gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{"chore: update docs", "refactor: method"}, nil).Once() + branchName := "feature/GH-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) + s.gitProvider.CommitsToPush[branchName] = []string{"commit 1", "commit 2"} s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue pushing all pending commits in this branch and create the pull request", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Once() - - s.expectCreatePullRequestNotCalled() - err := s.uc.Execute() s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should error if could not create empty commit", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CommitEmpty) - s.gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(assert.AnError).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) + branchName := "feature/GH-4-with-commit-error" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.BranchWithCommitError = []string{branchName} + s.setGetBranchName(branchName) err := s.uc.Execute() - s.ErrorContains(err, "could not do the empty commit because") - s.gitProvider.AssertNotCalled(s.T(), "PushBranch") - s.gitProvider.AssertExpectations(s.T()) + s.ErrorIs(err, domainFakes.ErrGetCommitsToPush) }) s.Run("should error if could not push branch", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Return(assert.AnError).Once() + branchName := "feature/GH-5-with-no-local-branch" + s.gitProvider.CurrentBranch = branchName + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, "could not create the remote branch because") - s.gitProvider.AssertExpectations(s.T()) }) s.Run("should error if could not create pull request", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", assert.AnError).Once() + branchName := "feature/GH-6-with-no-remote-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.LocalBranches = append(s.gitProvider.LocalBranches, branchName) + s.pullRequestProvider.PullRequestsWithErrors = []string{branchName} + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, "could not create the pull request because") - s.pullRequestProvider.AssertExpectations(s.T()) }) s.Run("should checkout local branch if branch exists and user confirms branch usage without default flag and issue flag", func() { mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutBranch) - s.gitProvider.EXPECT().CheckoutBranch("feature/GH-1-sample-issue").Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" @@ -268,6 +239,8 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti }) s.Run("should error if branch already exists when using default and issue flags", func() { + s.setGetBranchName(s.defaultBranchName) + s.uc.Cfg.IsInteractive = false s.uc.Cfg.IssueID = "1" @@ -276,12 +249,11 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti s.ErrorContains(err, "the branch feature/GH-1-sample-issue already exists") }) - s.Run("should abort execution if remote branch already exists when using issue flags", func() { + s.Run("should return error if remote branch already exists when using issue flags", func() { mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/GH-1-sample-issue").Return(true).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" @@ -289,24 +261,17 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists("feature/GH-1-sample-issue").Error()) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should create new branch name if user doesn't confirm default branch name when using issue flags", func() { + s.gitProvider.LocalBranches = []string{"main", "develop"} + s.gitProvider.RemoteBranches = []string{"main", "develop"} + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) - s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.FetchBranchFromOrigin) - s.gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutNewBranchFromOrigin) - s.gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/GH-1-sample-issue", "main").Return(nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/GH-1-sample-issue").Return(false).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" @@ -314,18 +279,16 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) }) - s.Run("should abort execution if user doesn't confirm branch name when using issue flags", func() { + s.Run("should return error if user doesn't confirm branch name when using issue flags", func() { + s.gitProvider.LocalBranches = []string{"main", "develop"} + s.gitProvider.RemoteBranches = []string{"main", "develop"} + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) - s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/GH-1-sample-issue").Return(false).Once() - - s.expectCreatePullRequestNotCalled() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "1" @@ -333,19 +296,13 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should checkout branch if user confirms branch usage with issue flag and no default flag", func() { mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() - s.gitProvider.EXPECT().CheckoutBranch("feature/GH-1-sample-issue").Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - s.uc.Cfg.IssueID = "1" err := s.uc.Execute() @@ -355,25 +312,19 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti }) s.Run("should not error if pull request is created correctly", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.gitProvider.RemoteBranches = []string{"main", "develop"} + branchName := "feature/GH-1-sample-issue" + s.gitProvider.CurrentBranch = branchName - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) + s.setGetBranchName(branchName) err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestCalled() + s.True(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should create branch and pull request if local branch doesn't exists with issue flag", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExistsContains) - s.gitProvider.EXPECT().BranchExistsContains("/GH-1-").Return("", false) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/GH-1-sample-issue").Return(false).Once() - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.SelectOrInputPrompt) s.userInteractionProvider.EXPECT().SelectOrInputPrompt("Label 'kind/feature' found. What type of branch name do you want to create?", []string{"feature", "other"}, mock.Anything, true).Return(nil).Once() s.userInteractionProvider.EXPECT().SelectOrInput("additional description (optional). Truncate to 29 chars", []string{}, mock.Anything, false).Return(nil).Once() @@ -381,90 +332,40 @@ func (s *CreateGithubPullRequestExecutionTestSuite) TestCreatePullRequestExecuti s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - s.uc.Cfg.IssueID = "1" err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestCalled() + s.True(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should create pull request with no close issue flag", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest("Sample issue", "Related to #1", "main", "feature/GH-1-sample-issue", true, []string{"kind/feature"}).Return("https://example.com", nil).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - s.expectNoPrFound() + branchName := "feature/GH-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) s.uc.Cfg.CloseIssue = false err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) + s.True(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should error if could not get issue", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.issueTracker.Mock, s.issueTracker.GetIssue) - s.issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{}, assert.AnError).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - s.expectCreatePullRequestNotCalled() + branchName := "feature/GH-6-with-no-remote-branch" + s.gitProvider.CurrentBranch = branchName + s.setGetBranchName(branchName) err := s.uc.Execute() s.Error(err) - s.issueTracker.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) } -func (s *CreateGithubPullRequestExecutionTestSuite) expectCreatePullRequestNotCalled() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Times(0) -} - -func (s *CreateGithubPullRequestExecutionTestSuite) assertCreatePullRequestNotCalled() { - s.pullRequestProvider.AssertNotCalled(s.T(), "CreatePullRequest") -} - -func (s *CreateGithubPullRequestExecutionTestSuite) assertCreatePullRequestCalled() { - s.pullRequestProvider.AssertCalled(s.T(), "CreatePullRequest", "Sample issue", "Closes #1", "main", "feature/GH-1-sample-issue", true, []string{"kind/feature"}) -} - -func (s *CreateGithubPullRequestExecutionTestSuite) expectNoPrFound() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() -} - -func (s *CreateGithubPullRequestExecutionTestSuite) initializeGitProvider() *domainMocks.MockGitProvider { - gitProvider := &domainMocks.MockGitProvider{} - - gitProvider.EXPECT().GetCurrentBranch().Return(s.defaultBranchName, nil).Maybe() - gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{}, nil).Maybe() - gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Maybe() - gitProvider.EXPECT().BranchExistsContains("/GH-1-").Return("feature/GH-1-sample-issue", true).Maybe() - gitProvider.EXPECT().BranchExists("/GH-1-").Return(true).Maybe() - - gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().PushBranch(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Maybe() - gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/GH-1-sample-issue", "main").Return(nil).Maybe() - - return gitProvider -} - func (s *CreateGithubPullRequestExecutionTestSuite) initializeUserInteractionProvider() *domainMocks.MockUserInteractionProvider { userInteractionProvider := &domainMocks.MockUserInteractionProvider{} @@ -475,69 +376,9 @@ func (s *CreateGithubPullRequestExecutionTestSuite) initializeUserInteractionPro return userInteractionProvider } -func (s *CreateGithubPullRequestExecutionTestSuite) initializePullRequestProvider() *domainMocks.MockPullRequestProvider { - pullRequestProvider := &domainMocks.MockPullRequestProvider{} - - pullRequestProvider.EXPECT().GetPullRequestForBranch(s.defaultBranchName).Return(&domain.PullRequest{ - Title: "Sample issue", - Number: 1, - State: "OPEN", - Closed: false, - Url: "https://example.com", - Labels: []domain.Label{}, - }, nil).Maybe() - - pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("https://example.com", nil).Maybe() - - return pullRequestProvider -} - -func (s *CreateGithubPullRequestExecutionTestSuite) initializeIssueTrackerProvider() *domainMocks.MockIssueTrackerProvider { - issueTrackerProvider := &domainMocks.MockIssueTrackerProvider{} - - // issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(GetDefaultIssueTracker(), nil).Maybe() - issueTrackerProvider.EXPECT().ParseIssueId(mock.Anything).Return("1").Maybe() - - return issueTrackerProvider -} - -func (s *CreateGithubPullRequestExecutionTestSuite) initializeRepositoryProvider() *domainMocks.MockRepositoryProvider { - repositoryProvider := &domainMocks.MockRepositoryProvider{} - - repositoryProvider.EXPECT().GetRepository().Return(&domain.Repository{ - Owner: "inditex", - Name: "gh-sherpa", - NameWithOwner: "InditexTech/gh-sherpa", - DefaultBranchRef: "main", - }, nil).Maybe() - - return repositoryProvider -} - -func (s *CreateGithubPullRequestExecutionTestSuite) initializeIssueTracker() *domainMocks.MockIssueTracker { - issueTracker := &domainMocks.MockIssueTracker{} - - issueTracker.EXPECT().FormatIssueId(mock.Anything).Return("GH-1").Maybe() - issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{ - ID: "1", - Title: "Sample issue", - Body: "Sample issue body", - Labels: []domain.Label{}, - IssueTracker: domain.IssueTrackerTypeGithub, - Url: "https://github.com/InditexTech/gh-sherpa/issues/1", - }, nil).Maybe() - issueTracker.EXPECT().GetIssueType(mock.Anything).Return(issue_types.Feature).Maybe() - issueTracker.EXPECT().GetIssueTrackerType().Return(domain.IssueTrackerTypeGithub).Maybe() - issueTracker.EXPECT().GetIssueTypeLabel(mock.Anything).Return("kind/feature").Maybe() - - return issueTracker -} - func (s *CreateGithubPullRequestExecutionTestSuite) initializeBranchProvider() *domainMocks.MockBranchProvider { branchProvider := &domainMocks.MockBranchProvider{} - branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return("feature/GH-1-sample-issue", nil).Maybe() - return branchProvider } @@ -572,16 +413,22 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TeardownTest() { } func (s *CreateJiraPullRequestExecutionTestSuite) SetupSubTest() { - s.gitProvider = s.initializeGitProvider() - s.issueTrackerProvider = s.initializeIssueTrackerProvider() + s.gitProvider = domainFakes.NewFakeGitProvider() + s.gitProvider.AddLocalBranches(s.defaultBranchName) + s.gitProvider.AddRemoteBranches(s.defaultBranchName) + + s.issueTracker = domainFakes.NewFakeIssueTracker() + s.issueTracker.IssueTrackerType = domain.IssueTrackerTypeJira + s.issueTracker.AddIssue("PROJECTKEY-1", issue_types.Feature) + s.issueTracker.AddIssue("PROJECTKEY-3", issue_types.Documentation) + s.issueTracker.AddIssue("PROJECTKEY-6", issue_types.Refactoring) + + s.issueTrackerProvider = domainFakes.NewFakeIssueTrackerProvider(s.issueTracker) + s.userInteractionProvider = s.initializeUserInteractionProvider() - s.pullRequestProvider = s.initializePullRequestProvider() - s.issueTracker = s.initializeIssueTracker() + s.pullRequestProvider = domainFakes.NewFakePullRequestProvider() s.branchProvider = s.initializeBranchProvider() - s.repositoryProvider = s.initializeRepositoryProvider() - - mocks.UnsetExpectedCall(&s.issueTrackerProvider.Mock, s.issueTrackerProvider.GetIssueTracker) - s.issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(s.issueTracker, nil).Maybe() + s.repositoryProvider = domainFakes.NewRepositoryProvider() defaultConfig := use_cases.CreatePullRequestConfiguration{ IsInteractive: true, @@ -602,186 +449,149 @@ func (s *CreateJiraPullRequestExecutionTestSuite) SetupSubTest() { func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution() { s.Run("should error if could not get git repository", func() { - mocks.UnsetExpectedCall(&s.repositoryProvider.Mock, s.repositoryProvider.GetRepository) - s.repositoryProvider.EXPECT().GetRepository().Return(nil, assert.AnError).Once() - - s.expectCreatePullRequestNotCalled() + s.repositoryProvider.Repository = nil err := s.uc.Execute() - s.Error(err) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.ErrorIs(err, domainFakes.ErrRepositoryNotFound) }) s.Run("should error if could not get current branch", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCurrentBranch) - s.gitProvider.EXPECT().GetCurrentBranch().Return("", assert.AnError).Once() - - s.expectCreatePullRequestNotCalled() + s.gitProvider.CurrentBranch = "" err := s.uc.Execute() s.ErrorContains(err, "could not get the current branch name") - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should error if no issue could be identified", func() { branchName := "branch-with-no-issue-name" - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCurrentBranch) - s.gitProvider.EXPECT().GetCurrentBranch().Return(branchName, nil).Once() - - s.expectCreatePullRequestNotCalled() + s.gitProvider.CurrentBranch = branchName err := s.uc.Execute() expectedError := fmt.Sprintf("could not find an issue identifier in the current branch named %s", branchName) s.EqualError(err, expectedError) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should exit if user does not confirm current branch", func() { + s.gitProvider.CurrentBranch = s.defaultBranchName + s.setGetBranchName(s.defaultBranchName) + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation(mock.Anything, mock.Anything).Return(false, nil).Once() - s.expectCreatePullRequestNotCalled() - err := s.uc.Execute() s.NoError(err) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.defaultBranchName)) }) s.Run("should return error if pr already exists", func() { - s.expectCreatePullRequestNotCalled() + branchName := "feature/PROJECTKEY-3-pull-request-sample" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.pullRequestProvider.AddPullRequest(branchName, domain.PullRequest{}) + s.setGetBranchName(branchName) err := s.uc.Execute() - s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists(s.defaultBranchName).Error()) - s.assertCreatePullRequestNotCalled() + s.ErrorContains(err, "pull request") + s.ErrorContains(err, "already exists") }) s.Run("should not ask the user for branch confirmation if default flag is used", func() { + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) s.uc.Cfg.IsInteractive = false - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - err := s.uc.Execute() s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) s.userInteractionProvider.AssertNotCalled(s.T(), "AskUserForConfirmation") }) - s.Run("should return error if remote branch already exists", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Once() - - s.expectCreatePullRequestNotCalled() + s.Run("should create and push empty commit if remote branch does not exists", func() { + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) err := s.uc.Execute() - s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists(s.defaultBranchName).Error()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.NoError(err) }) - s.Run("should create and push empty commit if remote branch does not exists", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CommitEmpty) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - s.gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Once() - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.Run("should return error if remote branch already exists", func() { + branchName := "feature/PROJECTKEY-1-sample-issue" + s.gitProvider.CurrentBranch = branchName + s.setGetBranchName(branchName) err := s.uc.Execute() - s.NoError(err) - s.gitProvider.AssertExpectations(s.T()) + s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists(s.defaultBranchName).Error()) + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should exit if user does not confirm the commit push when default flag is not used", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.GetCommitsToPush) - s.gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{"chore: update docs", "refactor: method"}, nil).Once() + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) + s.gitProvider.CommitsToPush[branchName] = []string{"commit 1", "commit 2"} s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue pushing all pending commits in this branch and create the pull request", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Once() - - s.expectCreatePullRequestNotCalled() - err := s.uc.Execute() s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) s.Run("should error if could not create empty commit", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CommitEmpty) - s.gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(assert.AnError).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) + branchName := "feature/PROJECTKEY-4-with-commit-error" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.BranchWithCommitError = []string{branchName} + s.setGetBranchName(branchName) err := s.uc.Execute() - s.ErrorContains(err, "could not do the empty commit because") - s.gitProvider.AssertNotCalled(s.T(), "PushBranch") - s.gitProvider.AssertExpectations(s.T()) + s.ErrorIs(err, domainFakes.ErrGetCommitsToPush) }) s.Run("should error if could not push branch", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.PushBranch) - s.gitProvider.EXPECT().PushBranch(s.defaultBranchName).Return(assert.AnError).Once() + branchName := "feature/PROJECTKEY-5-with-no-local-branch" + s.gitProvider.CurrentBranch = branchName + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, "could not create the remote branch because") - s.gitProvider.AssertExpectations(s.T()) }) s.Run("should error if could not create pull request", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", assert.AnError).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(mock.Anything).Return(false).Times(2) + branchName := "feature/PROJECTKEY-6-with-no-remote-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.LocalBranches = append(s.gitProvider.LocalBranches, branchName) + s.pullRequestProvider.PullRequestsWithErrors = []string{branchName} + s.setGetBranchName(branchName) err := s.uc.Execute() s.ErrorContains(err, "could not create the pull request because") - s.pullRequestProvider.AssertExpectations(s.T()) }) s.Run("should checkout local branch if branch exists and user confirms branch usage without default flag and issue flag", func() { mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutBranch) - s.gitProvider.EXPECT().CheckoutBranch("feature/PROJECTKEY-1-sample-issue").Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "PROJECTKEY-1" @@ -792,7 +602,7 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution }) s.Run("should error if branch already exists when using default and issue flags", func() { - s.uc.Cfg.IssueID = "1" + s.uc.Cfg.IssueID = "PROJECTKEY-1" s.uc.Cfg.IsInteractive = false err := s.uc.Execute() @@ -804,8 +614,7 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/PROJECTKEY-1-sample-issue").Return(true).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "PROJECTKEY-1" @@ -813,24 +622,17 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution s.ErrorContains(err, use_cases.ErrRemoteBranchAlreadyExists("feature/PROJECTKEY-1-sample-issue").Error()) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should create new branch name if user doesn't confirm default branch name when using issue flags", func() { + s.gitProvider.LocalBranches = []string{"main", "develop"} + s.gitProvider.RemoteBranches = []string{"main", "develop"} + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) - s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.FetchBranchFromOrigin) - s.gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.CheckoutNewBranchFromOrigin) - s.gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/PROJECTKEY-1-sample-issue", "main").Return(nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/PROJECTKEY-1-sample-issue").Return(false).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "PROJECTKEY-1" @@ -838,18 +640,16 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) }) - s.Run("should abort execution if user doesn't confirm branch name when using issue flags", func() { + s.Run("should return error if user doesn't confirm branch name when using issue flags", func() { + s.gitProvider.LocalBranches = []string{"main", "develop"} + s.gitProvider.RemoteBranches = []string{"main", "develop"} + mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) - s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(false, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(false, nil).Once() - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/PROJECTKEY-1-sample-issue").Return(false).Once() - - s.expectCreatePullRequestNotCalled() + s.setGetBranchName(s.defaultBranchName) s.uc.Cfg.IssueID = "PROJECTKEY-1" @@ -857,19 +657,13 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution s.NoError(err) s.userInteractionProvider.AssertExpectations(s.T()) - s.gitProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should checkout branch if user confirms branch usage with issue flag and no default flag", func() { mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.AskUserForConfirmation) s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() - s.gitProvider.EXPECT().CheckoutBranch("feature/PROJECTKEY-1-sample-issue").Return(nil).Once() - - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - s.uc.Cfg.IssueID = "PROJECTKEY-1" err := s.uc.Execute() @@ -879,25 +673,16 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution }) s.Run("should not error if pull request is created correctly", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(mock.Anything).Return(false).Times(2) + s.gitProvider.RemoteBranches = []string{"main", "develop"} + s.gitProvider.CurrentBranch = "feature/PROJECTKEY-1-sample-issue" err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestCalled() + s.True(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should create branch and pull request if local branch doesn't exists with issue flag", func() { - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.BranchExistsContains) - s.gitProvider.EXPECT().BranchExistsContains("/PROJECTKEY-1-").Return("", false) - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists("feature/PROJECTKEY-1-sample-issue").Return(false).Once() - mocks.UnsetExpectedCall(&s.userInteractionProvider.Mock, s.userInteractionProvider.SelectOrInputPrompt) s.userInteractionProvider.EXPECT().SelectOrInputPrompt("Issue type 'feature' found. What type of branch name do you want to create?", []string{"feature", "other"}, mock.Anything, true).Return(nil).Once() s.userInteractionProvider.EXPECT().SelectOrInput("additional description (optional). Truncate to 21 chars", []string{}, mock.Anything, false).Return(nil).Once() @@ -905,24 +690,19 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to use this branch to create the pull request", true).Return(true, nil).Once() s.userInteractionProvider.EXPECT().AskUserForConfirmation("Do you want to continue?", true).Return(true, nil).Once() - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - s.uc.Cfg.IssueID = "PROJECTKEY-1" err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) - s.assertCreatePullRequestCalled() + s.True(s.pullRequestProvider.HasPullRequestForBranch(s.gitProvider.CurrentBranch)) }) s.Run("should create pull request with no close issue flag", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest("[PROJECTKEY-1] Sample issue", "Relates to [PROJECTKEY-1](https://jira.example.com/browse/PROJECTKEY-1)", "main", "feature/PROJECTKEY-1-sample-issue", true, []string{"kind/feature"}).Return("https://example.com", nil).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) + branchName := "feature/PROJECTKEY-3-local-branch" + s.gitProvider.CurrentBranch = branchName + s.gitProvider.AddLocalBranches(branchName) + s.setGetBranchName(branchName) s.expectNoPrFound() @@ -931,62 +711,25 @@ func (s *CreateJiraPullRequestExecutionTestSuite) TestCreatePullRequestExecution err := s.uc.Execute() s.NoError(err) - s.pullRequestProvider.AssertExpectations(s.T()) }) s.Run("should error if could not get issue", func() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() - - mocks.UnsetExpectedCall(&s.issueTracker.Mock, s.issueTracker.GetIssue) - s.issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{}, assert.AnError).Once() - - mocks.UnsetExpectedCall(&s.gitProvider.Mock, s.gitProvider.RemoteBranchExists) - s.gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(false).Times(2) - - s.expectCreatePullRequestNotCalled() + branchName := "feature/PROJECTKEY-6-with-no-remote-branch" + s.gitProvider.CurrentBranch = branchName + s.setGetBranchName(branchName) err := s.uc.Execute() s.Error(err) - s.issueTracker.AssertExpectations(s.T()) - s.assertCreatePullRequestNotCalled() + s.False(s.pullRequestProvider.HasPullRequestForBranch(branchName)) }) } -func (s *CreateJiraPullRequestExecutionTestSuite) expectCreatePullRequestNotCalled() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.CreatePullRequest) - s.pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Times(0) -} - -func (s *CreateJiraPullRequestExecutionTestSuite) assertCreatePullRequestNotCalled() { - s.pullRequestProvider.AssertNotCalled(s.T(), "CreatePullRequest") -} - -func (s *CreateJiraPullRequestExecutionTestSuite) assertCreatePullRequestCalled() { - s.pullRequestProvider.AssertCalled(s.T(), "CreatePullRequest", "[PROJECTKEY-1] Sample issue", "Relates to [PROJECTKEY-1](https://jira.example.com/browse/PROJECTKEY-1)", "main", "feature/PROJECTKEY-1-sample-issue", true, []string{"kind/feature"}) -} - func (s *CreateJiraPullRequestExecutionTestSuite) expectNoPrFound() { - mocks.UnsetExpectedCall(&s.pullRequestProvider.Mock, s.pullRequestProvider.GetPullRequestForBranch) - s.pullRequestProvider.EXPECT().GetPullRequestForBranch(mock.Anything).Return(nil, nil).Once() -} - -func (s *CreateJiraPullRequestExecutionTestSuite) initializeGitProvider() *domainMocks.MockGitProvider { - gitProvider := &domainMocks.MockGitProvider{} - - gitProvider.EXPECT().GetCurrentBranch().Return(s.defaultBranchName, nil).Maybe() - gitProvider.EXPECT().GetCommitsToPush(s.defaultBranchName).Return([]string{}, nil).Maybe() - gitProvider.EXPECT().RemoteBranchExists(s.defaultBranchName).Return(true).Maybe() - gitProvider.EXPECT().BranchExistsContains("/PROJECTKEY-1-").Return("feature/PROJECTKEY-1-sample-issue", true).Maybe() - gitProvider.EXPECT().BranchExists("/PROJECTKEY-1-").Return(true).Maybe() - - gitProvider.EXPECT().CommitEmpty(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().PushBranch(mock.Anything).Return(nil).Maybe() - gitProvider.EXPECT().FetchBranchFromOrigin("main").Return(nil).Maybe() - gitProvider.EXPECT().CheckoutNewBranchFromOrigin("feature/PROJECTKEY-1-sample-issue", "main").Return(nil).Maybe() - - return gitProvider + branch := s.gitProvider.CurrentBranch + if pr := s.pullRequestProvider.PullRequests[branch]; pr != nil { + s.Failf("pull request exists for branch %s", branch) + } } func (s *CreateJiraPullRequestExecutionTestSuite) initializeUserInteractionProvider() *domainMocks.MockUserInteractionProvider { @@ -999,73 +742,8 @@ func (s *CreateJiraPullRequestExecutionTestSuite) initializeUserInteractionProvi return userInteractionProvider } -func (s *CreateJiraPullRequestExecutionTestSuite) initializePullRequestProvider() *domainMocks.MockPullRequestProvider { - pullRequestProvider := &domainMocks.MockPullRequestProvider{} - - pullRequestProvider.EXPECT().GetPullRequestForBranch(s.defaultBranchName).Return(&domain.PullRequest{ - Title: "Sample issue", - Number: 1, - State: "OPEN", - Closed: false, - Url: "https://example.com", - Labels: []domain.Label{}, - }, nil).Maybe() - - pullRequestProvider.EXPECT().CreatePullRequest(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("https://example.com", nil).Maybe() - - return pullRequestProvider -} - -func (s *CreateJiraPullRequestExecutionTestSuite) initializeIssueTrackerProvider() *domainMocks.MockIssueTrackerProvider { - issueTrackerProvider := &domainMocks.MockIssueTrackerProvider{} - - // issueTrackerProvider.EXPECT().GetIssueTracker(mock.Anything).Return(GetDefaultIssueTracker(), nil).Maybe() - issueTrackerProvider.EXPECT().ParseIssueId(mock.Anything).Return("1").Maybe() - - return issueTrackerProvider -} - -func (s *CreateJiraPullRequestExecutionTestSuite) initializeRepositoryProvider() *domainMocks.MockRepositoryProvider { - repositoryProvider := &domainMocks.MockRepositoryProvider{} - - repositoryProvider.EXPECT().GetRepository().Return(&domain.Repository{ - Owner: "inditex", - Name: "gh-sherpa", - NameWithOwner: "InditexTech/gh-sherpa", - DefaultBranchRef: "main", - }, nil).Maybe() - - return repositoryProvider -} - -func (s *CreateJiraPullRequestExecutionTestSuite) initializeIssueTracker() *domainMocks.MockIssueTracker { - issueTracker := &domainMocks.MockIssueTracker{} - - issueTracker.EXPECT().FormatIssueId(mock.Anything).Return("PROJECTKEY-1").Maybe() - issueTracker.EXPECT().GetIssue(mock.Anything).Return(domain.Issue{ - ID: "PROJECTKEY-1", - Title: "Sample issue", - Body: "Sample issue body", - Labels: []domain.Label{}, - IssueTracker: domain.IssueTrackerTypeJira, - Type: domain.IssueType{ - Id: "3", - Name: "feature", - Description: "A new feature of the product, which has to be developed and tested.", - }, - Url: "https://jira.example.com/browse/PROJECTKEY-1", - }, nil).Maybe() - issueTracker.EXPECT().GetIssueType(mock.Anything).Return(issue_types.Feature).Maybe() - issueTracker.EXPECT().GetIssueTrackerType().Return(domain.IssueTrackerTypeJira).Maybe() - issueTracker.EXPECT().GetIssueTypeLabel(mock.Anything).Return("kind/feature").Maybe() - - return issueTracker -} - func (s *CreateJiraPullRequestExecutionTestSuite) initializeBranchProvider() *domainMocks.MockBranchProvider { branchProvider := &domainMocks.MockBranchProvider{} - branchProvider.EXPECT().GetBranchName(mock.Anything, mock.Anything, mock.Anything).Return("feature/PROJECTKEY-1-sample-issue", nil).Maybe() - return branchProvider } diff --git a/sonar-project.properties b/sonar-project.properties index 71564c3..e1bf3a7 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -6,7 +6,7 @@ sonar.sourceEncoding=UTF-8 sonar.sources=. sonar.inclusions=**/*.go -sonar.exclusions=**/*_test.go, **/*.autogen.go, **/*.gen.go, **/mock_*.go +sonar.exclusions=**/*_test.go, **/*.autogen.go, **/*.gen.go, **/mock_*.go, **/fake_*go sonar.tests.inclusions=**/*_test.go