github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/github/create_issue_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package github
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"net/http"
    10  	"regexp"
    11  	"testing"
    12  
    13  	"github.com/google/go-github/v45/github"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  type ghCreateIssueMock struct {
    18  	issue      *github.IssueRequest
    19  	issueID    int64
    20  	issueError error
    21  	owner      string
    22  	repo       string
    23  	number     int
    24  	assignees  []string
    25  }
    26  
    27  func (g *ghCreateIssueMock) Create(ctx context.Context, owner string, repo string, issue *github.IssueRequest) (*github.Issue, *github.Response, error) {
    28  	g.issue = issue
    29  	g.owner = owner
    30  	g.repo = repo
    31  	g.assignees = *issue.Assignees
    32  
    33  	issueResponse := github.Issue{ID: &g.issueID, Title: issue.Title, Body: issue.Body}
    34  
    35  	ghRes := github.Response{Response: &http.Response{Status: "200"}}
    36  	if g.issueError != nil {
    37  		ghRes.Status = "401"
    38  	}
    39  
    40  	return &issueResponse, &ghRes, g.issueError
    41  }
    42  
    43  type ghSearchIssuesMock struct {
    44  	issueID            int64
    45  	issueNumber        int
    46  	issueTitle         string
    47  	issueBody          string
    48  	issuesSearchResult *github.IssuesSearchResult
    49  	issuesSearchError  error
    50  }
    51  
    52  func (g *ghSearchIssuesMock) Issues(ctx context.Context, query string, opts *github.SearchOptions) (*github.IssuesSearchResult, *github.Response, error) {
    53  	regex := regexp.MustCompile(`.*in:title (?P<Title>(.*))`)
    54  	matches := regex.FindStringSubmatch(query)
    55  
    56  	g.issueTitle = matches[1]
    57  
    58  	issues := []*github.Issue{
    59  		{
    60  			ID:     &g.issueID,
    61  			Number: &g.issueNumber,
    62  			Title:  &g.issueTitle,
    63  			Body:   &g.issueBody,
    64  		},
    65  	}
    66  
    67  	total := len(issues)
    68  	incompleteResults := false
    69  
    70  	g.issuesSearchResult = &github.IssuesSearchResult{
    71  		Issues:            issues,
    72  		Total:             &total,
    73  		IncompleteResults: &incompleteResults,
    74  	}
    75  
    76  	ghRes := github.Response{Response: &http.Response{Status: "200"}}
    77  	if g.issuesSearchError != nil {
    78  		ghRes.Status = "401"
    79  	}
    80  
    81  	return g.issuesSearchResult, &ghRes, g.issuesSearchError
    82  }
    83  
    84  type ghCreateCommentMock struct {
    85  	issueComment      *github.IssueComment
    86  	issueNumber       int
    87  	issueCommentError error
    88  }
    89  
    90  func (g *ghCreateCommentMock) CreateComment(ctx context.Context, owner string, repo string, number int, comment *github.IssueComment) (*github.IssueComment, *github.Response, error) {
    91  	g.issueComment = comment
    92  	g.issueNumber = number
    93  	ghRes := github.Response{Response: &http.Response{Status: "200"}}
    94  	if g.issueCommentError != nil {
    95  		ghRes.Status = "401"
    96  	}
    97  	return g.issueComment, &ghRes, g.issueCommentError
    98  }
    99  
   100  func TestRunGithubCreateIssue(t *testing.T) {
   101  	ctx := context.Background()
   102  	t.Parallel()
   103  
   104  	t.Run("Success", func(t *testing.T) {
   105  		// init
   106  		ghCreateIssueService := ghCreateIssueMock{
   107  			issueID: 1,
   108  		}
   109  		ghSearchIssuesMock := ghSearchIssuesMock{
   110  			issueID: 1,
   111  		}
   112  		ghCreateCommentMock := ghCreateCommentMock{}
   113  		config := CreateIssueOptions{
   114  			Owner:      "TEST",
   115  			Repository: "test",
   116  			Body:       []byte("This is my test body"),
   117  			Title:      "This is my title",
   118  			Assignees:  []string{"userIdOne", "userIdTwo"},
   119  		}
   120  
   121  		// test
   122  		_, err := createIssueLocal(ctx, &config, &ghCreateIssueService, &ghSearchIssuesMock, &ghCreateCommentMock)
   123  
   124  		// assert
   125  		assert.NoError(t, err)
   126  		assert.Equal(t, config.Owner, ghCreateIssueService.owner)
   127  		assert.Equal(t, config.Repository, ghCreateIssueService.repo)
   128  		assert.Equal(t, "This is my test body", ghCreateIssueService.issue.GetBody())
   129  		assert.Equal(t, config.Title, ghCreateIssueService.issue.GetTitle())
   130  		assert.Equal(t, config.Assignees, ghCreateIssueService.issue.GetAssignees())
   131  		assert.Nil(t, ghSearchIssuesMock.issuesSearchResult)
   132  		assert.Nil(t, ghCreateCommentMock.issueComment)
   133  	})
   134  
   135  	t.Run("Success update existing", func(t *testing.T) {
   136  		// init
   137  		ghSearchIssuesMock := ghSearchIssuesMock{
   138  			issueID: 1,
   139  		}
   140  		ghCreateCommentMock := ghCreateCommentMock{}
   141  		config := CreateIssueOptions{
   142  			Owner:          "TEST",
   143  			Repository:     "test",
   144  			Body:           []byte("This is my test body"),
   145  			Title:          "This is my title",
   146  			Assignees:      []string{"userIdOne", "userIdTwo"},
   147  			UpdateExisting: true,
   148  		}
   149  
   150  		// test
   151  		_, err := createIssueLocal(ctx, &config, nil, &ghSearchIssuesMock, &ghCreateCommentMock)
   152  
   153  		// assert
   154  		assert.NoError(t, err)
   155  		assert.NotNil(t, ghSearchIssuesMock.issuesSearchResult)
   156  		assert.NotNil(t, ghCreateCommentMock.issueComment)
   157  		assert.Equal(t, config.Title, ghSearchIssuesMock.issueTitle)
   158  		assert.Equal(t, config.Title, *ghSearchIssuesMock.issuesSearchResult.Issues[0].Title)
   159  		assert.Equal(t, "This is my test body", ghCreateCommentMock.issueComment.GetBody())
   160  	})
   161  
   162  	t.Run("Success update existing based on instance", func(t *testing.T) {
   163  		// init
   164  		ghSearchIssuesMock := ghSearchIssuesMock{
   165  			issueID: 1,
   166  		}
   167  		ghCreateCommentMock := ghCreateCommentMock{}
   168  		var id int64 = 2
   169  		var number int = 123
   170  		config := CreateIssueOptions{
   171  			Owner:          "TEST",
   172  			Repository:     "test",
   173  			Body:           []byte("This is my test body"),
   174  			Title:          "This is my title",
   175  			Assignees:      []string{"userIdOne", "userIdTwo"},
   176  			UpdateExisting: true,
   177  			Issue: &github.Issue{
   178  				ID:     &id,
   179  				Number: &number,
   180  			},
   181  		}
   182  
   183  		// test
   184  		_, err := createIssueLocal(ctx, &config, nil, &ghSearchIssuesMock, &ghCreateCommentMock)
   185  
   186  		// assert
   187  		assert.NoError(t, err)
   188  		assert.Nil(t, ghSearchIssuesMock.issuesSearchResult)
   189  		assert.NotNil(t, ghCreateCommentMock.issueComment)
   190  		assert.Equal(t, ghCreateCommentMock.issueNumber, number)
   191  		assert.Equal(t, "This is my test body", ghCreateCommentMock.issueComment.GetBody())
   192  	})
   193  
   194  	t.Run("Empty body", func(t *testing.T) {
   195  		// init
   196  		ghCreateIssueService := ghCreateIssueMock{
   197  			issueID: 1,
   198  		}
   199  		ghSearchIssuesMock := ghSearchIssuesMock{
   200  			issueID: 1,
   201  		}
   202  		ghCreateCommentMock := ghCreateCommentMock{}
   203  		config := CreateIssueOptions{
   204  			Owner:          "TEST",
   205  			Repository:     "test",
   206  			Body:           []byte(""),
   207  			Title:          "This is my title",
   208  			Assignees:      []string{"userIdOne", "userIdTwo"},
   209  			UpdateExisting: true,
   210  		}
   211  
   212  		// test
   213  		_, err := createIssueLocal(ctx, &config, &ghCreateIssueService, &ghSearchIssuesMock, &ghCreateCommentMock)
   214  
   215  		// assert
   216  		assert.NoError(t, err)
   217  		assert.NotNil(t, ghSearchIssuesMock.issuesSearchResult)
   218  		assert.NotNil(t, ghCreateCommentMock.issueComment)
   219  		assert.Equal(t, config.Title, ghSearchIssuesMock.issueTitle)
   220  		assert.Equal(t, config.Title, *ghSearchIssuesMock.issuesSearchResult.Issues[0].Title)
   221  		assert.Equal(t, "", ghCreateCommentMock.issueComment.GetBody())
   222  	})
   223  
   224  	t.Run("Create error", func(t *testing.T) {
   225  		// init
   226  		ghCreateIssueService := ghCreateIssueMock{
   227  			issueError: fmt.Errorf("error creating issue"),
   228  		}
   229  		config := CreateIssueOptions{
   230  			Body: []byte("test content"),
   231  		}
   232  
   233  		// test
   234  		_, err := createIssueLocal(ctx, &config, &ghCreateIssueService, nil, nil)
   235  
   236  		// assert
   237  		assert.EqualError(t, err, "error occurred when creating issue: error creating issue")
   238  	})
   239  }