Skip to content

Commit

Permalink
feat(github): add IsPushable function and tests
Browse files Browse the repository at this point in the history
Added a new function IsPushable to check if a user has push permissions
based on the viewerPermission API query.

Added new util file in the github package to include helper functions
and facilitate unit testing on command outputs.
  • Loading branch information
sledigabel committed Oct 9, 2024
1 parent 55ca75f commit f46bc9b
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions internal/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ func (r *RealGitHub) GetPR(output io.Writer, workingDir string, branchName strin
return nil, &NoPRFoundError{Path: workingDir, BranchName: branchName}
}

func (r *RealGitHub) IsPushable(output io.Writer, workingDir string, fullRepoName string) (bool, error) {
s, err := execInstance.ExecuteAndCapture(output, workingDir, "gh", "repo", "view", fullRepoName, "--json", "viewerPermission")
if err != nil {
return false, err
}

return IsPushable(s)
}

func NewRealGitHub() *RealGitHub {
return &RealGitHub{}
}
42 changes: 42 additions & 0 deletions internal/github/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2021 Skyscanner Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

// util contains helper functions needed for both real and fake implementations of the GitHub interface

package github

import "encoding/json"

type ViewerPermission struct {
ViewerPermission string `json:"viewerPermission"`
}

// IsPushable checks the output of the viewerPermission API query
// and returns true if the user has write, maintain or admin permissions

func IsPushable(viewerPermissionOutput string) (bool, error) {
var vp ViewerPermission

if err := json.Unmarshal([]byte(viewerPermissionOutput), &vp); err != nil {
return false, err
}

switch vp.ViewerPermission {
case "WRITE", "MAINTAIN", "ADMIN":
return true, nil
default:
return false, nil
}
}
65 changes: 65 additions & 0 deletions internal/github/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2021 Skyscanner Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package github

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestIsPushableReturnsTrueForAllCases(t *testing.T) {
testCases := []string{
`{"viewerPermission":"WRITE"}`,
`{"viewerPermission":"MAINTAIN"}`,
`{"viewerPermission":"ADMIN"}`,
}

for _, testCase := range testCases {
pushable, err := IsPushable(testCase)
assert.NoError(t, err)
assert.True(t, pushable)
}
}

func TestIsPushableReturnsFalseForUnknownPermission(t *testing.T) {
testCases := []string{
`{"viewerPermission":"UNKNOWN"}`,
`{"viewerPermission":"READ"}`,
`{"viewerPermission":"RANDOM"}`,
`{"viewerPermission":""}`,
}

for _, testCase := range testCases {
pushable, err := IsPushable(testCase)
assert.NoError(t, err)
assert.False(t, pushable)
}
}

func TestIsPushableReturnsErrorForInvalidJSON(t *testing.T) {
testCases := []string{
`{"anotherParam":"WRITE"`, // valid JSON but not the expected format
`{"viewerPermission":"WRITE"`, // invalid JSON
`viewerPermission: WRITE`, // invalid JSON
`{"viewerPermission": WRITE}`, // invalid JSON
}

for _, testCase := range testCases {
_, err := IsPushable(testCase)
assert.Error(t, err)
}
}

0 comments on commit f46bc9b

Please sign in to comment.