2019-11-04 17:07:30 +02:00
package cmd
import (
2019-11-05 15:37:44 +02:00
"context"
2019-11-04 17:07:30 +02:00
"fmt"
2019-11-05 15:37:44 +02:00
"net/http"
"os"
"path/filepath"
2019-11-04 17:07:30 +02:00
"testing"
2019-11-05 15:37:44 +02:00
"time"
2019-11-04 17:07:30 +02:00
"github.com/google/go-github/v28/github"
"github.com/stretchr/testify/assert"
)
2019-11-05 15:37:44 +02:00
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
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
}
2020-02-14 15:56:23 +02:00
if len ( owner ) == 0 {
return g . latestRelease , nil , g . latestErr
}
2019-11-05 15:37:44 +02:00
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
}
2019-11-04 17:07:30 +02:00
func TestRunGithubPublishRelease ( t * testing . T ) {
2019-11-05 15:37:44 +02:00
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" ,
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
ServerURL : "https://github.com" ,
2019-11-05 15:37:44 +02:00
ReleaseBodyHeader : "Header" ,
Version : "1.0" ,
}
err := runGithubPublishRelease ( ctx , & myGithubPublishReleaseOptions , & ghRepoClient , & ghIssueClient )
assert . NoError ( t , err , "Error occured but none expected." )
assert . Equal ( t , "Header\n" , ghRepoClient . release . GetBody ( ) )
} )
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" ,
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
ServerURL : "https://github.com" ,
2019-11-05 15:37:44 +02:00
ReleaseBodyHeader : "Header" ,
Version : "1.1" ,
}
err := runGithubPublishRelease ( ctx , & myGithubPublishReleaseOptions , & ghRepoClient , & ghIssueClient )
assert . NoError ( t , err , "Error occured 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 {
2019-11-21 17:34:22 +02:00
AssetPath : filepath . Join ( "testdata" , t . Name ( ) + "_test.txt" ) ,
Version : "latest" ,
2019-11-05 15:37:44 +02:00
}
err := runGithubPublishRelease ( ctx , & myGithubPublishReleaseOptions , & ghRepoClient , & ghIssueClient )
assert . NoError ( t , err , "Error occured 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" ) ,
}
2020-02-14 15:56:23 +02:00
myGithubPublishReleaseOptions := githubPublishReleaseOptions {
Owner : "TEST" ,
Repository : "test" ,
}
err := runGithubPublishRelease ( ctx , & myGithubPublishReleaseOptions , & ghRepoClient , & ghIssueClient )
assert . Equal ( t , "Error occured 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" ,
}
2019-11-05 15:37:44 +02:00
err := runGithubPublishRelease ( ctx , & myGithubPublishReleaseOptions , & ghRepoClient , & ghIssueClient )
2020-02-14 15:56:23 +02:00
assert . Equal ( t , "Error occured when retrieving latest GitHub release (/test): Latest release error, no response" , fmt . Sprint ( err ) )
2019-11-05 15:37:44 +02:00
} )
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 {
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
2019-11-05 15:37:44 +02:00
}
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 {
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
ServerURL : "https://github.com" ,
Version : "1.1" ,
2019-11-05 15:37:44 +02:00
}
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 {
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
2019-11-05 15:37:44 +02:00
AssetPath : filepath . Join ( "testdata" , t . Name ( ) + "_test.txt" ) ,
}
err := uploadReleaseAsset ( ctx , releaseID , & myGithubPublishReleaseOptions , & ghRepoClient )
assert . NoError ( t , err , "Error occured 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 {
2019-11-05 16:13:04 +02:00
Owner : "TEST" ,
Repository : "test" ,
2019-11-05 15:37:44 +02:00
AssetPath : filepath . Join ( "testdata" , t . Name ( ) + "_test.txt" ) ,
}
err := uploadReleaseAsset ( ctx , releaseID , & myGithubPublishReleaseOptions , & ghRepoClient )
assert . NoError ( t , err , "Error occured 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 { }
2019-11-04 17:07:30 +02:00
2019-11-05 15:37:44 +02:00
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" )
} )
2019-11-04 17:07:30 +02:00
}
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 ) )
}
}