Skip to content

Commit

Permalink
Merge branch 'main' of github.com:sonatype-nexus-community/the-cla
Browse files Browse the repository at this point in the history
  • Loading branch information
madpah committed Sep 27, 2024
2 parents f4fdad5 + 6fc9cd5 commit 62e2338
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 111 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ RUN REACT_APP_CLA_URL="$REACT_APP_CLA_URL" \
REACT_APP_CLA_VERSION="$REACT_APP_CLA_VERSION" \
make yarn

FROM golang:1.21-alpine AS build
FROM golang:1.22-alpine AS build
LABEL stage=builder

RUN apk add --no-cache build-base ca-certificates git
Expand Down
2 changes: 0 additions & 2 deletions github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// limitations under the License.
//

//go:build go1.16

package github

import (
Expand Down
103 changes: 54 additions & 49 deletions github/github_mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,63 @@
// limitations under the License.
//

//go:build go1.16

package github

import (
"context"
"net/http"
"os"
"reflect"
"testing"

"github.com/google/go-github/v64/github"
"github.com/stretchr/testify/assert"
)

type assertParams struct {
/* number of index/times the production function has been called by production code, zero based. */
callIndex int
/* assertParameters is a slice of booleans that determine whether to assert the parameters passed to the function for
each call to the production function. If the value at the index of the callIndex is true, the actual parameters will be
asserted against the expected parameters. */
assertParameters []bool
/* expectedParameters is a slice of any types of slices that contains the expected parameters that should be passed
to the production function during the running of test. */
expectedParameters []any
}

func (a *assertParams) doAssert(t assert.TestingT, actualParameters []any) {
for i, expParams := range a.expectedParameters {
refExpParams := reflect.ValueOf(expParams)
assert.Equal(t, reflect.Slice, refExpParams.Kind(), "expected parameters must be a slice")
epForThisCall := refExpParams.Index(a.callIndex).Interface()
assert.Equal(t, epForThisCall, actualParameters[i])
}
}

// RepositoriesMock mocks RepositoriesService
type RepositoriesMock struct {
t *testing.T
/* callCount is the number of times the CreateStatus function has been called by production code. */
callCount int
/* assertParameters is a slice of booleans that determine whether to assert the parameters passed to the function for
each call to the CreateStatus function. If the value at the index of the callCount is true, the parameters will be
asserted.
*/
assertParameters []bool
expectedCtx []context.Context
expectedOwner, expectedRepo, expectedRef, expectedUser []string
// expectedOpts *github.ListOptions
expectedCreateStatusRepoStatus []*github.RepoStatus
createStatusRepoStatus []*github.RepoStatus
createStatusResponse []*github.Response
createStatusError []error
isCollaboratorResult bool
isCollaboratorResp *github.Response
isCollaboratorErr error
t *testing.T
assertParamsCreateStatus assertParams
createStatusRepoStatus []*github.RepoStatus
createStatusResponse []*github.Response
createStatusError []error
isCollaboratorResult bool
isCollaboratorResp *github.Response
isCollaboratorErr error
}

var _ RepositoriesService = (*RepositoriesMock)(nil)

func setupMockRepositoriesService(t *testing.T, assertParameters []bool) (mock *RepositoriesMock) {
func setupMockRepositoriesService(t *testing.T, assertParameters []bool, expectedParams []any) (mock *RepositoriesMock) {
mock = &RepositoriesMock{
t: t,
assertParameters: assertParameters,
t: t,
assertParamsCreateStatus: assertParams{
assertParameters: assertParameters,
expectedParameters: expectedParams,
},
}

return mock
}

Expand All @@ -67,35 +81,22 @@ func (r *RepositoriesMock) ListStatuses(ctx context.Context, owner, repo, ref st
}

func (r *RepositoriesMock) CreateStatus(ctx context.Context, owner, repo, ref string, status *github.RepoStatus) (retRepoStatus *github.RepoStatus, createStatusResponse *github.Response, createStatusError error) {
defer func() { r.callCount++ }()
if r.assertParameters != nil && r.assertParameters[r.callCount] {
if r.expectedCtx != nil {
assert.Equal(r.t, r.expectedCtx[r.callCount], ctx)
}
if r.expectedOwner != nil {
assert.Equal(r.t, r.expectedOwner[r.callCount], owner)
}
if r.expectedRepo != nil {
assert.Equal(r.t, r.expectedRepo[r.callCount], repo)
}
if r.expectedRef != nil {
assert.Equal(r.t, r.expectedRef[r.callCount], ref)
}
if r.expectedCreateStatusRepoStatus != nil {
assert.Equal(r.t, r.expectedCreateStatusRepoStatus[r.callCount], status)
}
defer func() { r.assertParamsCreateStatus.callIndex++ }()
if r.assertParamsCreateStatus.assertParameters != nil && r.assertParamsCreateStatus.assertParameters[r.assertParamsCreateStatus.callIndex] {
actualParameters := []any{ctx, owner, repo, ref, status}
r.assertParamsCreateStatus.doAssert(r.t, actualParameters)
}

if r.createStatusRepoStatus != nil {
retRepoStatus = r.createStatusRepoStatus[r.callCount]
retRepoStatus = r.createStatusRepoStatus[r.assertParamsCreateStatus.callIndex]
}

if r.createStatusRepoStatus != nil {
createStatusResponse = r.createStatusResponse[r.callCount]
createStatusResponse = r.createStatusResponse[r.assertParamsCreateStatus.callIndex]
}

if r.createStatusError != nil {
createStatusError = r.createStatusError[r.callCount]
createStatusError = r.createStatusError[r.assertParamsCreateStatus.callIndex]
}
return
}
Expand All @@ -113,13 +114,8 @@ func (r *RepositoriesMock) Get(context.Context, string, string) (*github.Reposit
}, nil, nil
}

//goland:noinspection GoUnusedParameter
func (r *RepositoriesMock) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *github.Response, error) {
if r.assertParameters != nil && r.assertParameters[r.callCount] {
assert.Equal(r.t, r.expectedCtx[r.callCount], ctx)
assert.Equal(r.t, r.expectedOwner[r.callCount], owner)
assert.Equal(r.t, r.expectedRepo[r.callCount], repo)
assert.Equal(r.t, r.expectedUser[r.callCount], user)
}
return r.isCollaboratorResult, r.isCollaboratorResp, r.isCollaboratorErr
}

Expand Down Expand Up @@ -152,6 +148,8 @@ func (p *PullRequestsMock) ListCommits(ctx context.Context, owner string, repo s
}

type IssuesMock struct {
t *testing.T
assertParamsCreateComment assertParams
mockGetLabel *github.Label
MockGetLabelResponse *github.Response
mockGetLabelError error
Expand Down Expand Up @@ -203,6 +201,11 @@ func (i *IssuesMock) RemoveLabelForIssue(ctx context.Context, owner string, repo

//goland:noinspection GoUnusedParameter
func (i *IssuesMock) CreateComment(ctx context.Context, owner string, repo string, number int, comment *github.IssueComment) (*github.IssueComment, *github.Response, error) {
defer func() { i.assertParamsCreateComment.callIndex++ }()
if i.assertParamsCreateComment.assertParameters != nil && i.assertParamsCreateComment.assertParameters[i.assertParamsCreateComment.callIndex] {
actualParameters := []any{ctx, owner, repo, number, comment}
i.assertParamsCreateComment.doAssert(i.t, actualParameters)
}
return i.mockComment, i.mockCreateCommentResponse, i.mockCreateCommentError
}

Expand Down Expand Up @@ -290,6 +293,8 @@ func (g *GHInterfaceMock) NewClient(httpClient *http.Client) GHClient {
mockResponse: g.PullRequestsMock.mockResponse,
},
Issues: &IssuesMock{
t: g.IssuesMock.t,
assertParamsCreateComment: g.IssuesMock.assertParamsCreateComment,
mockGetLabel: g.IssuesMock.mockGetLabel,
MockGetLabelResponse: g.IssuesMock.MockGetLabelResponse,
mockGetLabelError: g.IssuesMock.mockGetLabelError,
Expand Down
60 changes: 42 additions & 18 deletions github/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// limitations under the License.
//

//go:build go1.16

package github

import (
Expand Down Expand Up @@ -351,7 +349,7 @@ func TestWithFullEnvironment(t *testing.T) {
t.Run("TestHandlePullRequestListCommitsError", func(t *testing.T) {
forcedError := fmt.Errorf("forced ListCommits error")
GHImpl = &GHInterfaceMock{
RepositoriesMock: *setupMockRepositoriesService(t, []bool{false}),
RepositoriesMock: *setupMockRepositoriesService(t, []bool{false}, nil),
PullRequestsMock: PullRequestsMock{
mockListCommitsError: forcedError,
},
Expand Down Expand Up @@ -390,21 +388,26 @@ func TestWithFullEnvironment(t *testing.T) {
t.Run("TestHandlePullRequestListCommitsUnsignedCommit", func(t *testing.T) {
authors := []string{"john", "doe"}

repositoriesMock := *setupMockRepositoriesService(t, []bool{true, true})
repositoriesMock.expectedCtx = []context.Context{context.Background(), context.Background()}

repositoriesMock.expectedCreateStatusRepoStatus = []*github.RepoStatus{
{
State: github.String("pending"),
Description: github.String("Paul Botsco, the CLA verifier is running"),
Context: &MockAppSlug,
},
{
State: github.String("failure"),
Description: github.String("One or more commits haven't met our Quality requirements."),
Context: &MockAppSlug,
},
}
repositoriesMock := *setupMockRepositoriesService(t,
[]bool{true, true},
[]any{
[]context.Context{context.Background(), context.Background()}, // ctx
[]string{"", ""}, // owner
[]string{"", ""}, // repo
[]string{"", ""}, // sha
[]*github.RepoStatus{
{
State: github.String("pending"),
Description: github.String("Paul Botsco, the CLA verifier is running"),
Context: &MockAppSlug,
},
{
State: github.String("failure"),
Description: github.String("One or more commits haven't met our Quality requirements."),
Context: &MockAppSlug,
},
},
})

GHImpl = getGHMock(getMockRepositoryCommits(authors, false), nil, &repositoriesMock)
mockDB, logger := setupMockDB(t, false)
Expand Down Expand Up @@ -542,6 +545,27 @@ func TestHandlePullRequestListCommitsNoAuthor(t *testing.T) {
mockRepositoryCommits: mockRepositoryCommits,
},
IssuesMock: IssuesMock{
t: t,
assertParamsCreateComment: assertParams{
assertParameters: []bool{true},
expectedParameters: []any{
[]context.Context{context.Background()}, // ctx
[]string{""}, // owner
[]string{""}, // repo
[]int{0}, // number
[]*github.IssueComment{
{Body: github.String(
`Thanks for the contribution. Unfortunately some of your commits don't meet our standards. All commits must be signed and have author information set.
The commits to review are:
- <a href="https://github.com">johnSHA</a> - missing author :cop:
- <a href="https://github.com">johnSHA</a> - unsigned commit :key:
`,
)},
}, // comment
},
},
mockGetLabel: &github.Label{},
MockGetLabelResponse: &github.Response{
Response: &http.Response{},
Expand Down
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
module github.com/sonatype-nexus-community/the-cla

go 1.21
go 1.22.0

toolchain go1.21.7
toolchain go1.22.7

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/bradleyfalzon/ghinstallation/v2 v2.11.0
github.com/golang-migrate/migrate/v4 v4.17.1
github.com/golang-migrate/migrate/v4 v4.18.1
github.com/google/go-github/v64 v64.0.0
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
github.com/labstack/echo/v4 v4.12.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
golang.org/x/oauth2 v0.21.0
golang.org/x/oauth2 v0.23.0
gopkg.in/go-playground/webhooks.v5 v5.17.0
)

Expand All @@ -35,10 +35,10 @@ require (
github.com/valyala/fasttemplate v1.2.2 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 62e2338

Please sign in to comment.