1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/cmd/githubPublishRelease_test.go
Christopher Fenner b219fb6514
fix(typo): found by misspell (#2064)
* fix typos in step yamls

* fix typos in go files

* regenerate step code

* fix typos in md files

* fix typos in groovy files

* fix further typos
2020-09-24 07:41:06 +02:00

408 lines
14 KiB
Go

package cmd
import (
"context"
"fmt"
"net/http"
"os"
"path/filepath"
"testing"
"time"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
)
type ghRCMock struct {
createErr error
latestRelease *github.RepositoryRelease
release *github.RepositoryRelease
delErr error
delID int64
delOwner string
delRepo string
listErr error
listID int64
listOwner string
listReleaseAssets []*github.ReleaseAsset
listRepo string
listOpts *github.ListOptions
latestStatusCode int
latestErr error
preRelease bool
uploadID int64
uploadOpts *github.UploadOptions
uploadOwner string
uploadRepo string
}
func (g *ghRCMock) CreateRelease(ctx context.Context, owner string, repo string, release *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error) {
g.release = release
return release, nil, g.createErr
}
func (g *ghRCMock) DeleteReleaseAsset(ctx context.Context, owner string, repo string, id int64) (*github.Response, error) {
g.delOwner = owner
g.delRepo = repo
g.delID = id
return nil, g.delErr
}
func (g *ghRCMock) GetLatestRelease(ctx context.Context, owner string, repo string) (*github.RepositoryRelease, *github.Response, error) {
hc := http.Response{StatusCode: 200}
if g.latestStatusCode != 0 {
hc.StatusCode = g.latestStatusCode
}
if len(owner) == 0 {
return g.latestRelease, nil, g.latestErr
}
ghResp := github.Response{Response: &hc}
return g.latestRelease, &ghResp, g.latestErr
}
func (g *ghRCMock) ListReleaseAssets(ctx context.Context, owner string, repo string, id int64, opt *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error) {
g.listID = id
g.listOwner = owner
g.listRepo = repo
g.listOpts = opt
return g.listReleaseAssets, nil, g.listErr
}
func (g *ghRCMock) UploadReleaseAsset(ctx context.Context, owner string, repo string, id int64, opt *github.UploadOptions, file *os.File) (*github.ReleaseAsset, *github.Response, error) {
g.uploadID = id
g.uploadOwner = owner
g.uploadRepo = repo
g.uploadOpts = opt
return nil, nil, nil
}
type ghICMock struct {
issues []*github.Issue
lastPublished time.Time
owner string
repo string
options *github.IssueListByRepoOptions
}
func (g *ghICMock) ListByRepo(ctx context.Context, owner string, repo string, opt *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error) {
g.owner = owner
g.repo = repo
g.options = opt
g.lastPublished = opt.Since
return g.issues, nil, nil
}
func TestRunGithubPublishRelease(t *testing.T) {
ctx := context.Background()
t.Run("Success - first release & no body", func(t *testing.T) {
ghIssueClient := ghICMock{}
ghRepoClient := ghRCMock{
latestStatusCode: 404,
latestErr: fmt.Errorf("not found"),
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
AddDeltaToLastRelease: true,
Commitish: "master",
Owner: "TEST",
PreRelease: true,
Repository: "test",
ServerURL: "https://github.com",
ReleaseBodyHeader: "Header",
Version: "1.0",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.NoError(t, err, "Error occurred but none expected.")
assert.Equal(t, "Header\n", ghRepoClient.release.GetBody())
assert.Equal(t, true, ghRepoClient.release.GetPrerelease())
})
t.Run("Success - subsequent releases & with body", func(t *testing.T) {
lastTag := "1.0"
lastPublishedAt := github.Timestamp{Time: time.Date(2019, 01, 01, 0, 0, 0, 0, time.UTC)}
ghRepoClient := ghRCMock{
createErr: nil,
latestRelease: &github.RepositoryRelease{
TagName: &lastTag,
PublishedAt: &lastPublishedAt,
},
}
prHTMLURL := "https://github.com/TEST/test/pull/1"
prTitle := "Pull"
prNo := 1
issHTMLURL := "https://github.com/TEST/test/issues/2"
issTitle := "Issue"
issNo := 2
ghIssueClient := ghICMock{
issues: []*github.Issue{
{Number: &prNo, Title: &prTitle, HTMLURL: &prHTMLURL, PullRequestLinks: &github.PullRequestLinks{URL: &prHTMLURL}},
{Number: &issNo, Title: &issTitle, HTMLURL: &issHTMLURL},
},
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
AddClosedIssues: true,
AddDeltaToLastRelease: true,
Commitish: "master",
Owner: "TEST",
Repository: "test",
ServerURL: "https://github.com",
ReleaseBodyHeader: "Header",
Version: "1.1",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.NoError(t, err, "Error occurred but none expected.")
assert.Equal(t, "Header\n\n**List of closed pull-requests since last release**\n[#1](https://github.com/TEST/test/pull/1): Pull\n\n**List of closed issues since last release**\n[#2](https://github.com/TEST/test/issues/2): Issue\n\n**Changes**\n[1.0...1.1](https://github.com/TEST/test/compare/1.0...1.1)\n", ghRepoClient.release.GetBody())
assert.Equal(t, "1.1", ghRepoClient.release.GetName())
assert.Equal(t, "1.1", ghRepoClient.release.GetTagName())
assert.Equal(t, "master", ghRepoClient.release.GetTargetCommitish())
assert.Equal(t, lastPublishedAt.Time, ghIssueClient.lastPublished)
})
t.Run("Success - update asset", func(t *testing.T) {
var releaseID int64 = 1
ghIssueClient := ghICMock{}
ghRepoClient := ghRCMock{
latestRelease: &github.RepositoryRelease{
ID: &releaseID,
},
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
AssetPath: filepath.Join("testdata", t.Name()+"_test.txt"),
Version: "latest",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.NoError(t, err, "Error occurred but none expected.")
assert.Nil(t, ghRepoClient.release)
assert.Equal(t, releaseID, ghRepoClient.listID)
assert.Equal(t, releaseID, ghRepoClient.uploadID)
})
t.Run("Error - get release", func(t *testing.T) {
ghIssueClient := ghICMock{}
ghRepoClient := ghRCMock{
latestErr: fmt.Errorf("Latest release error"),
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "TEST",
Repository: "test",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.Equal(t, "Error occurred when retrieving latest GitHub release (TEST/test): Latest release error", fmt.Sprint(err))
})
t.Run("Error - get release no response", func(t *testing.T) {
ghIssueClient := ghICMock{}
ghRepoClient := ghRCMock{
latestErr: fmt.Errorf("Latest release error, no response"),
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "",
Repository: "test",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.Equal(t, "Error occurred when retrieving latest GitHub release (/test): Latest release error, no response", fmt.Sprint(err))
})
t.Run("Error - create release", func(t *testing.T) {
ghIssueClient := ghICMock{}
ghRepoClient := ghRCMock{
createErr: fmt.Errorf("Create release error"),
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Version: "1.0",
}
err := runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, &ghRepoClient, &ghIssueClient)
assert.Equal(t, "Creation of release '1.0' failed: Create release error", fmt.Sprint(err))
})
}
func TestGetClosedIssuesText(t *testing.T) {
ctx := context.Background()
publishedAt := github.Timestamp{Time: time.Date(2019, 01, 01, 0, 0, 0, 0, time.UTC)}
t.Run("No issues", func(t *testing.T) {
ghIssueClient := ghICMock{}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Version: "1.0",
}
res := getClosedIssuesText(ctx, publishedAt, &myGithubPublishReleaseOptions, &ghIssueClient)
assert.Equal(t, "", res)
})
t.Run("All issues", func(t *testing.T) {
ctx := context.Background()
publishedAt := github.Timestamp{Time: time.Date(2019, 01, 01, 0, 0, 0, 0, time.UTC)}
prHTMLURL := []string{"https://github.com/TEST/test/pull/1", "https://github.com/TEST/test/pull/2"}
prTitle := []string{"Pull1", "Pull2"}
prNo := []int{1, 2}
issHTMLURL := []string{"https://github.com/TEST/test/issues/3", "https://github.com/TEST/test/issues/4"}
issTitle := []string{"Issue3", "Issue4"}
issNo := []int{3, 4}
ghIssueClient := ghICMock{
issues: []*github.Issue{
{Number: &prNo[0], Title: &prTitle[0], HTMLURL: &prHTMLURL[0], PullRequestLinks: &github.PullRequestLinks{URL: &prHTMLURL[0]}},
{Number: &prNo[1], Title: &prTitle[1], HTMLURL: &prHTMLURL[1], PullRequestLinks: &github.PullRequestLinks{URL: &prHTMLURL[1]}},
{Number: &issNo[0], Title: &issTitle[0], HTMLURL: &issHTMLURL[0]},
{Number: &issNo[1], Title: &issTitle[1], HTMLURL: &issHTMLURL[1]},
},
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "TEST",
Repository: "test",
}
res := getClosedIssuesText(ctx, publishedAt, &myGithubPublishReleaseOptions, &ghIssueClient)
assert.Equal(t, "\n**List of closed pull-requests since last release**\n[#1](https://github.com/TEST/test/pull/1): Pull1\n[#2](https://github.com/TEST/test/pull/2): Pull2\n\n**List of closed issues since last release**\n[#3](https://github.com/TEST/test/issues/3): Issue3\n[#4](https://github.com/TEST/test/issues/4): Issue4\n", res)
assert.Equal(t, "TEST", ghIssueClient.owner, "Owner not properly passed")
assert.Equal(t, "test", ghIssueClient.repo, "Repo not properly passed")
assert.Equal(t, "closed", ghIssueClient.options.State, "Issue state not properly passed")
assert.Equal(t, "asc", ghIssueClient.options.Direction, "Sort direction not properly passed")
assert.Equal(t, publishedAt.Time, ghIssueClient.options.Since, "PublishedAt not properly passed")
})
}
func TestGetReleaseDeltaText(t *testing.T) {
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "TEST",
Repository: "test",
ServerURL: "https://github.com",
Version: "1.1",
}
lastTag := "1.0"
lastRelease := github.RepositoryRelease{
TagName: &lastTag,
}
res := getReleaseDeltaText(&myGithubPublishReleaseOptions, &lastRelease)
assert.Equal(t, "\n**Changes**\n[1.0...1.1](https://github.com/TEST/test/compare/1.0...1.1)\n", res)
}
func TestUploadReleaseAsset(t *testing.T) {
ctx := context.Background()
t.Run("Success - existing asset", func(t *testing.T) {
var releaseID int64 = 1
assetName := "Success_-_existing_asset_test.txt"
var assetID int64 = 11
ghRepoClient := ghRCMock{
latestRelease: &github.RepositoryRelease{
ID: &releaseID,
},
listReleaseAssets: []*github.ReleaseAsset{
{Name: &assetName, ID: &assetID},
},
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "TEST",
Repository: "test",
AssetPath: filepath.Join("testdata", t.Name()+"_test.txt"),
}
err := uploadReleaseAsset(ctx, releaseID, &myGithubPublishReleaseOptions, &ghRepoClient)
assert.NoError(t, err, "Error occurred but none expected.")
assert.Equal(t, "TEST", ghRepoClient.listOwner, "Owner not properly passed - list")
assert.Equal(t, "test", ghRepoClient.listRepo, "Repo not properly passed - list")
assert.Equal(t, releaseID, ghRepoClient.listID, "Relase ID not properly passed - list")
assert.Equal(t, "TEST", ghRepoClient.delOwner, "Owner not properly passed - del")
assert.Equal(t, "test", ghRepoClient.delRepo, "Repo not properly passed - del")
assert.Equal(t, assetID, ghRepoClient.delID, "Relase ID not properly passed - del")
assert.Equal(t, "TEST", ghRepoClient.uploadOwner, "Owner not properly passed - upload")
assert.Equal(t, "test", ghRepoClient.uploadRepo, "Repo not properly passed - upload")
assert.Equal(t, releaseID, ghRepoClient.uploadID, "Relase ID not properly passed - upload")
assert.Equal(t, "text/plain; charset=utf-8", ghRepoClient.uploadOpts.MediaType, "Wrong MediaType passed - upload")
})
t.Run("Success - no asset", func(t *testing.T) {
var releaseID int64 = 1
assetName := "notFound"
var assetID int64 = 11
ghRepoClient := ghRCMock{
latestRelease: &github.RepositoryRelease{
ID: &releaseID,
},
listReleaseAssets: []*github.ReleaseAsset{
{Name: &assetName, ID: &assetID},
},
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{
Owner: "TEST",
Repository: "test",
AssetPath: filepath.Join("testdata", t.Name()+"_test.txt"),
}
err := uploadReleaseAsset(ctx, releaseID, &myGithubPublishReleaseOptions, &ghRepoClient)
assert.NoError(t, err, "Error occurred but none expected.")
assert.Equal(t, int64(0), ghRepoClient.delID, "Relase ID should not be populated")
})
t.Run("Error - List Assets", func(t *testing.T) {
var releaseID int64 = 1
ghRepoClient := ghRCMock{
listErr: fmt.Errorf("List Asset Error"),
}
myGithubPublishReleaseOptions := githubPublishReleaseOptions{}
err := uploadReleaseAsset(ctx, releaseID, &myGithubPublishReleaseOptions, &ghRepoClient)
assert.Equal(t, "Failed to get list of release assets.: List Asset Error", fmt.Sprint(err), "Wrong error received")
})
}
func TestIsExcluded(t *testing.T) {
l1 := "label1"
l2 := "label2"
tt := []struct {
issue *github.Issue
excludeLabels []string
expected bool
}{
{issue: nil, excludeLabels: nil, expected: false},
{issue: &github.Issue{}, excludeLabels: nil, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: nil, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: []string{"label0"}, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}}}, excludeLabels: []string{"label1"}, expected: true},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{}, expected: false},
{issue: &github.Issue{Labels: []*github.Label{{Name: &l1}, {Name: &l2}}}, excludeLabels: []string{"label1"}, expected: true},
}
for k, v := range tt {
assert.Equal(t, v.expected, isExcluded(v.issue, v.excludeLabels), fmt.Sprintf("Run %v failed", k))
}
}