github.com/jenkins-x/jx/v2@v2.1.155/pkg/gits/bitbucket_cloud_test.go (about)

     1  // +build unit
     2  
     3  package gits_test
     4  
     5  import (
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"github.com/jenkins-x/jx/v2/pkg/auth"
    11  	"github.com/jenkins-x/jx/v2/pkg/gits"
    12  	"github.com/jenkins-x/jx/v2/pkg/util"
    13  	"github.com/stretchr/testify/suite"
    14  	bitbucket "github.com/wbrefvem/go-bitbucket"
    15  )
    16  
    17  type UserProfile struct {
    18  	name     string
    19  	url      string
    20  	username string
    21  }
    22  
    23  type BitbucketCloudProviderTestSuite struct {
    24  	suite.Suite
    25  	mux       *http.ServeMux
    26  	server    *httptest.Server
    27  	provider  gits.BitbucketCloudProvider
    28  	providers map[string]gits.BitbucketCloudProvider
    29  }
    30  
    31  const (
    32  	orgName = "test-org"
    33  )
    34  
    35  var profiles = []UserProfile{
    36  	{
    37  		url:      "https://auth.example.com",
    38  		name:     "Test Auth Server",
    39  		username: "test-user",
    40  	},
    41  	{
    42  		url:      "https://auth.example.com",
    43  		name:     "Test Auth Server with Underscore user",
    44  		username: "test_user",
    45  	},
    46  }
    47  
    48  var bitbucketRouter = util.Router{
    49  	"/repositories/test-user": util.MethodMap{
    50  		"GET": "repos.json",
    51  	},
    52  	"/repositories/test_user": util.MethodMap{
    53  		"GET": "repos.json",
    54  	},
    55  	"/repositories/test-user/test-repo": util.MethodMap{
    56  		"GET":    "repos.test-repo.json",
    57  		"DELETE": "repos.test-repo.nil.json",
    58  		"PUT":    "repos.test-repo-renamed.json",
    59  	},
    60  	"/repositories/test-user/test-repo/forks": util.MethodMap{
    61  		"POST": "repos.test-fork.json",
    62  	},
    63  	"/repositories/test-user/test-repo/pullrequests": util.MethodMap{
    64  		"POST": "pullrequests.test-repo.json",
    65  	},
    66  	"/repositories/test-org/test-repo/pullrequests": util.MethodMap{
    67  		"POST": "pullrequests.test-org.test-repo.json",
    68  	},
    69  	"/repositories/test-user/test-repo/pullrequests/3/": util.MethodMap{
    70  		"GET": "pullrequests.test-repo-closed.json",
    71  	},
    72  	"/repositories/test-org/test-repo/pullrequests/4/": util.MethodMap{
    73  		"GET": "pullrequests.test-org.test-repo-closed.json",
    74  	},
    75  	"/repositories/test-user/test-repo/pullrequests/1/commits": util.MethodMap{
    76  		"GET": "pullrequests.test-user.test-repo.1.json",
    77  	},
    78  	"/repositories/test-user/test-repo/pullrequests/3/commits": util.MethodMap{
    79  		"GET": "pullrequests.test-repo.commits.json",
    80  	},
    81  	"/repositories/test-org/test-repo/pullrequests/4/commits": util.MethodMap{
    82  		"GET": "pullrequests.test-org.test-repo.commits.json",
    83  	},
    84  	"/repositories/test-user/test-repo/commit/5c8afc5/statuses": util.MethodMap{
    85  		"GET": "repos.test-repo.statuses.json",
    86  	},
    87  	"/repositories/test-user/test-repo/commit/7793466f879b83f1bdd8f3fc3f761bc3cb61bc41": util.MethodMap{
    88  		"GET": "repos.test-user.test-repo.commits.7793466f879b83f1bdd8f3fc3f761bc3cb61bc41.json",
    89  	},
    90  	"/repositories/test-user/test-repo/commit/bbc7b863a56144647a806646b73e3b43749decad": util.MethodMap{
    91  		"GET": "repos.test-user.test-repo.commits.bbc7b863a56144647a806646b73e3b43749decad.json",
    92  	},
    93  	"/repositories/test-user/test-repo/pullrequests/1/merge": util.MethodMap{
    94  		"POST": "pullrequests.test-repo.merged.json",
    95  	},
    96  	"/repositories/test-user/test-repo/hooks": util.MethodMap{
    97  		"POST": "webhooks.example.json",
    98  	},
    99  	"/repositories/test-user/test-repo/issues": util.MethodMap{
   100  		"POST": "issues.test-repo.issue-1.json",
   101  		"GET":  "issues.test-repo.json",
   102  	},
   103  	"/repositories/test-user/test-repo/issues/1": util.MethodMap{
   104  		"GET": "issues.test-repo.issue-1.json",
   105  	},
   106  	"/users/test-user": util.MethodMap{
   107  		"GET": "users.test-user.json",
   108  	},
   109  	"/repositories/test-user/test-repo/pullrequests/1/comments": util.MethodMap{
   110  		"POST": "pullrequests.test-comment.json",
   111  	},
   112  	"/repositories/test-user/test-repo/issues/1/comments": util.MethodMap{
   113  		"POST": "issue-comments.issue-1.json",
   114  	},
   115  }
   116  
   117  func setupGitProvider(url, name, user string) (gits.GitProvider, error) {
   118  	as := auth.AuthServer{
   119  		URL:         url,
   120  		Name:        "Test Auth Server",
   121  		Kind:        "Oauth2",
   122  		CurrentUser: user,
   123  	}
   124  	ua := auth.UserAuth{
   125  		Username: user,
   126  		ApiToken: "0123456789abdef",
   127  	}
   128  
   129  	git := gits.NewGitCLI()
   130  	bp, err := gits.NewBitbucketCloudProvider(&as, &ua, git)
   131  
   132  	return bp, err
   133  }
   134  
   135  func (suite *BitbucketCloudProviderTestSuite) SetupSuite() {
   136  	suite.mux = http.NewServeMux()
   137  
   138  	for path, methodMap := range bitbucketRouter {
   139  		suite.mux.HandleFunc(path, util.GetMockAPIResponseFromFile("test_data/bitbucket_cloud", methodMap))
   140  	}
   141  
   142  	suite.server = httptest.NewServer(suite.mux)
   143  	suite.Require().NotNil(suite.server)
   144  
   145  	cfg := bitbucket.NewConfiguration()
   146  	cfg.BasePath = suite.server.URL
   147  
   148  	clientSingleton := bitbucket.NewAPIClient(cfg)
   149  	suite.providers = map[string]gits.BitbucketCloudProvider{}
   150  
   151  	for _, profile := range profiles {
   152  		gp, err := setupGitProvider(profile.url, profile.name, profile.username)
   153  
   154  		suite.Require().NotNil(gp)
   155  		suite.Require().Nil(err)
   156  
   157  		var ok bool
   158  		bp, ok := gp.(*gits.BitbucketCloudProvider)
   159  
   160  		suite.Require().NotNil(bp)
   161  		suite.Require().True(ok)
   162  		bp.Client = clientSingleton
   163  
   164  		suite.providers[profile.username] = *bp
   165  	}
   166  
   167  	suite.provider = suite.providers["test-user"]
   168  
   169  }
   170  
   171  func (suite *BitbucketCloudProviderTestSuite) TestListRepositories() {
   172  
   173  	for username, provider := range suite.providers {
   174  		repos, err := provider.ListRepositories(username)
   175  		suite.Require().Nil(err)
   176  		suite.Require().NotNil(repos)
   177  
   178  		suite.Require().Equal(len(repos), 2)
   179  
   180  		for _, repo := range repos {
   181  			suite.Require().NotNil(repo)
   182  		}
   183  	}
   184  }
   185  
   186  func (suite *BitbucketCloudProviderTestSuite) TestGetRepository() {
   187  
   188  	repo, err := suite.provider.GetRepository(
   189  		suite.provider.Username,
   190  		"test-repo",
   191  	)
   192  
   193  	suite.Require().NotNil(repo)
   194  	suite.Require().Nil(err)
   195  
   196  	suite.Require().Equal(repo.Name, "test-repo")
   197  }
   198  
   199  func (suite *BitbucketCloudProviderTestSuite) TestDeleteRepository() {
   200  
   201  	err := suite.provider.DeleteRepository(
   202  		suite.provider.Username,
   203  		"test-repo",
   204  	)
   205  
   206  	suite.Require().Nil(err)
   207  }
   208  
   209  func (suite *BitbucketCloudProviderTestSuite) TestForkRepository() {
   210  
   211  	fork, err := suite.provider.ForkRepository(
   212  		suite.provider.Username,
   213  		"test-repo",
   214  		"",
   215  	)
   216  
   217  	suite.Require().NotNil(fork)
   218  	suite.Require().Nil(err)
   219  
   220  	suite.Require().Equal(fork.Name, "test-fork")
   221  }
   222  
   223  func (suite *BitbucketCloudProviderTestSuite) TestValidateRepositoryName() {
   224  
   225  	err := suite.provider.ValidateRepositoryName(suite.provider.Username, "test-repo")
   226  
   227  	suite.Require().NotNil(err)
   228  
   229  	err = suite.provider.ValidateRepositoryName(suite.provider.Username, "foo-repo")
   230  
   231  	suite.Require().Nil(err)
   232  }
   233  
   234  func (suite *BitbucketCloudProviderTestSuite) TestRenameRepository() {
   235  
   236  	repo, err := suite.provider.RenameRepository(suite.provider.Username, "test-repo", "test-repo-renamed")
   237  
   238  	suite.Require().Nil(err)
   239  	suite.Require().NotNil(repo)
   240  
   241  	suite.Require().Equal(repo.Name, "test-repo-renamed")
   242  }
   243  
   244  func (suite *BitbucketCloudProviderTestSuite) TestCreatePullRequest() {
   245  	args := gits.GitPullRequestArguments{
   246  		GitRepository: &gits.GitRepository{Name: "test-repo", Organisation: "test-user"},
   247  		Head:          "83777f6",
   248  		Base:          "77d0a923f297",
   249  		Title:         "Test Pull Request",
   250  	}
   251  
   252  	pr, err := suite.provider.CreatePullRequest(&args)
   253  
   254  	suite.Require().NotNil(pr)
   255  	suite.Require().Nil(err)
   256  	suite.Require().Equal(*pr.State, "OPEN")
   257  	suite.Require().Equal(*pr.Number, 3)
   258  	suite.Require().Equal(pr.Owner, "test-user")
   259  	suite.Require().Equal(pr.Repo, "test-repo")
   260  	suite.Require().Equal(pr.Author.Login, "test-user")
   261  }
   262  
   263  func (suite *BitbucketCloudProviderTestSuite) TestCreateOrgPullRequest() {
   264  	args := gits.GitPullRequestArguments{
   265  		GitRepository: &gits.GitRepository{Name: "test-repo", Organisation: "test-org"},
   266  		Head:          "83777f6",
   267  		Base:          "77d0a923f297",
   268  		Title:         "Test Pull Request",
   269  	}
   270  
   271  	pr, err := suite.provider.CreatePullRequest(&args)
   272  
   273  	suite.Require().NotNil(pr)
   274  	suite.Require().Nil(err)
   275  	suite.Require().Equal(*pr.State, "OPEN")
   276  	suite.Require().Equal(*pr.Number, 4)
   277  	suite.Require().Equal(pr.Owner, "test-org")
   278  	suite.Require().Equal(pr.Repo, "test-repo")
   279  	suite.Require().Equal(pr.Author.Login, "test-user")
   280  }
   281  
   282  func (suite *BitbucketCloudProviderTestSuite) TestUpdatePullRequestStatus() {
   283  	number := 3
   284  	state := "OPEN"
   285  
   286  	pr := &gits.GitPullRequest{
   287  		Owner:  "test-user",
   288  		Repo:   "test-repo",
   289  		Number: &number,
   290  		State:  &state,
   291  	}
   292  
   293  	err := suite.provider.UpdatePullRequestStatus(pr)
   294  
   295  	suite.Require().NotNil(pr)
   296  	suite.Require().Nil(err)
   297  	suite.Require().Equal(*pr.State, "DECLINED")
   298  	suite.Require().Equal(*pr.Number, 3)
   299  	suite.Require().Equal(pr.Owner, "test-user")
   300  	suite.Require().Equal(pr.Repo, "test-repo")
   301  	suite.Require().Equal(pr.Author.Login, "test-user")
   302  }
   303  
   304  func (suite *BitbucketCloudProviderTestSuite) TestUpdateOrgPullRequestStatus() {
   305  	number := 4
   306  	state := "OPEN"
   307  
   308  	pr := &gits.GitPullRequest{
   309  		Owner:  "test-org",
   310  		Repo:   "test-repo",
   311  		Number: &number,
   312  		State:  &state,
   313  	}
   314  
   315  	err := suite.provider.UpdatePullRequestStatus(pr)
   316  
   317  	suite.Require().NotNil(pr)
   318  	suite.Require().Nil(err)
   319  	suite.Require().Equal(*pr.State, "DECLINED")
   320  	suite.Require().Equal(*pr.Number, 4)
   321  	suite.Require().Equal(pr.Owner, "test-org")
   322  	suite.Require().Equal(pr.Repo, "test-repo")
   323  	suite.Require().Equal(pr.Author.Login, "test-user")
   324  }
   325  
   326  func (suite *BitbucketCloudProviderTestSuite) TestGetPullRequest() {
   327  
   328  	pr, err := suite.provider.GetPullRequest(
   329  		"test-user",
   330  		&gits.GitRepository{Name: "test-repo"},
   331  		3,
   332  	)
   333  
   334  	suite.Require().Nil(err)
   335  	suite.Require().Equal(*pr.Number, 3)
   336  }
   337  
   338  func (suite *BitbucketCloudProviderTestSuite) TestPullRequestCommits() {
   339  	commits, err := suite.provider.GetPullRequestCommits("test-user", &gits.GitRepository{Name: "test-repo"}, 1)
   340  
   341  	suite.Require().Nil(err)
   342  	suite.Require().Equal(len(commits), 2)
   343  	suite.Require().Equal(commits[0].Author.Email, "test-user@gmail.com")
   344  }
   345  
   346  func (suite *BitbucketCloudProviderTestSuite) TestPullRequestLastCommitStatus() {
   347  
   348  	pr := &gits.GitPullRequest{
   349  		Owner:         "test-user",
   350  		Repo:          "test-repo",
   351  		LastCommitSha: "5c8afc5",
   352  	}
   353  	lastCommitStatus, err := suite.provider.PullRequestLastCommitStatus(pr)
   354  
   355  	suite.Require().Nil(err)
   356  	suite.Require().NotEmpty(lastCommitStatus)
   357  	suite.Require().Equal(lastCommitStatus, "in-progress")
   358  }
   359  
   360  func (suite *BitbucketCloudProviderTestSuite) testStatuses(statuses []*gits.GitRepoStatus, err error) {
   361  	suite.Require().Nil(err)
   362  	suite.Require().NotNil(statuses)
   363  	suite.Require().Equal(len(statuses), 2)
   364  
   365  	for _, status := range statuses {
   366  		if status.ID == "ffffffffbf8d2a62" {
   367  			suite.Require().Equal(status.State, "success")
   368  		} else if status.ID == "626bb1b3" {
   369  			suite.Require().Equal(status.State, "in-progress")
   370  		}
   371  		suite.Require().NotEmpty(status.State)
   372  		suite.Require().NotEmpty(status.URL)
   373  	}
   374  }
   375  
   376  func (suite *BitbucketCloudProviderTestSuite) TestListCommitStatus() {
   377  	statuses, err := suite.provider.ListCommitStatus("test-user", "test-repo", "5c8afc5")
   378  	suite.testStatuses(statuses, err)
   379  
   380  	statuses, err = suite.provider.ListCommitStatus("test-user", "test-repo", "5c8afc5")
   381  	suite.testStatuses(statuses, err)
   382  }
   383  
   384  func (suite *BitbucketCloudProviderTestSuite) TestMergePullRequest() {
   385  
   386  	id := 1
   387  	pr := &gits.GitPullRequest{
   388  		Owner:  "test-user",
   389  		Repo:   "test-repo",
   390  		Number: &id,
   391  	}
   392  	err := suite.provider.MergePullRequest(pr, "Merging from unit tests")
   393  
   394  	suite.Require().Nil(err)
   395  }
   396  
   397  func (suite *BitbucketCloudProviderTestSuite) TestCreateWebHook() {
   398  
   399  	data := &gits.GitWebHookArguments{
   400  		Repo: &gits.GitRepository{Name: "test-repo", Organisation: "test-user"},
   401  		URL:  "https://my-jenkins.example.com/bitbucket-webhook/",
   402  	}
   403  	err := suite.provider.CreateWebHook(data)
   404  
   405  	suite.Require().Nil(err)
   406  }
   407  
   408  func (suite *BitbucketCloudProviderTestSuite) TestSearchIssues() {
   409  	issues, err := suite.provider.SearchIssues("test-user", "test-repo", "")
   410  
   411  	suite.Require().Nil(err)
   412  	suite.Require().NotNil(issues)
   413  
   414  	for _, issue := range issues {
   415  		suite.Require().NotNil(issue)
   416  	}
   417  }
   418  
   419  func (suite *BitbucketCloudProviderTestSuite) TestGetIssue() {
   420  	issue, err := suite.provider.GetIssue("test-user", "test-repo", 1)
   421  
   422  	suite.Require().Nil(err)
   423  	suite.Require().NotNil(issue)
   424  	suite.Require().Equal(*issue.Number, 1)
   425  }
   426  
   427  func (suite *BitbucketCloudProviderTestSuite) TestCreateIssue() {
   428  
   429  	issueToCreate := &gits.GitIssue{
   430  		Title: "This is a test issue",
   431  	}
   432  
   433  	issue, err := suite.provider.CreateIssue("test-user", "test-repo", issueToCreate)
   434  
   435  	suite.Require().Nil(err)
   436  	suite.Require().NotNil(issue)
   437  }
   438  
   439  func (suite *BitbucketCloudProviderTestSuite) TestAddPRComment() {
   440  	comment := "This is my comment. There are many like it but this one is mine."
   441  	prNumber := 1
   442  
   443  	pr := &gits.GitPullRequest{
   444  		Number: &prNumber,
   445  		Owner:  "test-user",
   446  		Repo:   "test-repo",
   447  	}
   448  	err := suite.provider.AddPRComment(pr, comment)
   449  	suite.Require().Nil(err)
   450  
   451  	pr = &gits.GitPullRequest{
   452  		Number: &prNumber,
   453  		Owner:  "test-user",
   454  	}
   455  	err = suite.provider.AddPRComment(pr, comment)
   456  	suite.Require().NotNil(err)
   457  }
   458  
   459  func (suite *BitbucketCloudProviderTestSuite) TestCreateIssueComment() {
   460  	comment := "This is my comment. There are many like it but this one is mine."
   461  
   462  	err := suite.provider.CreateIssueComment(
   463  		"test-user",
   464  		"test-repo",
   465  		1,
   466  		comment,
   467  	)
   468  	suite.Require().Nil(err)
   469  
   470  	err = suite.provider.CreateIssueComment(
   471  		"test-user",
   472  		"test-repo",
   473  		0,
   474  		comment,
   475  	)
   476  	suite.Require().NotNil(err)
   477  }
   478  
   479  func (suite *BitbucketCloudProviderTestSuite) TestUpdateRelease() {
   480  	err := suite.provider.UpdateRelease("", "", "", nil)
   481  	suite.Require().Nil(err)
   482  }
   483  
   484  func (suite *BitbucketCloudProviderTestSuite) TestUserInfo() {
   485  	user := suite.provider.UserInfo("test-user")
   486  	suite.Require().NotNil(user)
   487  	suite.Require().Equal("test-user", user.Login)
   488  }
   489  
   490  func (suite *BitbucketCloudProviderTestSuite) TestAddCollaborator() {
   491  	err := suite.provider.AddCollaborator("derek", orgName, "repo")
   492  	suite.Require().Nil(err)
   493  }
   494  
   495  func (suite *BitbucketCloudProviderTestSuite) TestListInvitations() {
   496  	invites, res, err := suite.provider.ListInvitations()
   497  	suite.Require().NotNil(invites)
   498  	suite.Require().NotNil(res)
   499  	suite.Require().Nil(err)
   500  }
   501  
   502  func (suite *BitbucketCloudProviderTestSuite) TestAcceptInvitations() {
   503  	res, err := suite.provider.AcceptInvitation(1)
   504  	suite.Require().NotNil(res)
   505  	suite.Require().Nil(err)
   506  }
   507  
   508  func TestBitbucketCloudProviderTestSuite(t *testing.T) {
   509  	if testing.Short() {
   510  		t.Skip("skipping BitbucketCloudProviderTestSuite in short mode")
   511  	} else {
   512  		suite.Run(t, new(BitbucketCloudProviderTestSuite))
   513  	}
   514  }
   515  
   516  func (suite *BitbucketCloudProviderTestSuite) TearDownSuite() {
   517  	suite.server.Close()
   518  }