Skip to content

Commit

Permalink
tests: add unit tests for github package
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickMenoti committed Jul 8, 2024
1 parent 52fb5a2 commit ae9f823
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 17 deletions.
4 changes: 3 additions & 1 deletion pkg/cmd/root/pre_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ func checkForUpdateAndMetrics(cVersion string, f *cmdutil.Factory, settings *tok
metric.Send(settings)
}

tagName, err := github.GetVersionGitHub("azion")
git := github.NewGithub()

tagName, err := git.GetVersionGitHub("azion")
if err != nil {
return err
}
Expand Down
45 changes: 29 additions & 16 deletions pkg/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,36 @@ import (
gitignore "github.com/sabhiram/go-gitignore"
)

type Github struct {
GetVersionGitHub func(name string) (string, error)
Clone func(url, path string) error
GetNameRepo func(url string) string
CheckGitignore func(path string) (bool, error)
WriteGitignore func(path string) error
}

type Release struct {
TagName string `json:"tag_name"`
}

func GetVersionGitHub(name string) (string, error) {
apiURL := fmt.Sprintf("https://api.github.com/repos/aziontech/%s/releases/latest", name)
var (
ApiURL string
)

func NewGithub() *Github {
return &Github{
GetVersionGitHub: getVersionGitHub,
Clone: clone,
GetNameRepo: getNameRepo,
CheckGitignore: checkGitignore,
WriteGitignore: writeGitignore,
}
}

func getVersionGitHub(name string) (string, error) {
ApiURL = fmt.Sprintf("https://api.github.com/repos/aziontech/%s/releases/latest", name)

response, err := http.Get(apiURL)
response, err := http.Get(ApiURL)
if err != nil {
logger.Debug("Failed to get latest version of "+name, zap.Error(err))
return "", err
Expand All @@ -53,8 +75,7 @@ func GetVersionGitHub(name string) (string, error) {
return release.TagName, nil
}

// Clone clone the repository using git
func Clone(url, path string) error {
func clone(url, path string) error {
_, err := git.PlainClone(path, false, &git.CloneOptions{
URL: url,
})
Expand All @@ -67,24 +88,19 @@ func Clone(url, path string) error {
return nil
}

// GetNameRepoFunction to get the repository name from the URL
func GetNameRepo(url string) string {
// Remove the initial part of the URL
func getNameRepo(url string) string {
parts := strings.Split(url, "/")
repoPart := parts[len(parts)-1]
// Remove the .git folder if it exists.
repoPart = strings.TrimSuffix(repoPart, ".git")
return repoPart
}

func CheckGitignore(path string) (bool, error) {
func checkGitignore(path string) (bool, error) {
logger.Debug("Checking .gitignore file for existence of Vulcan files")
path = filepath.Join(path, ".gitignore")

object, err := gitignore.CompileIgnoreFile(path)
if err != nil {
// if the error is "no such file or directory" we can return false and nil for error, because the code that called this func will create
// the .gitignore file
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
Expand All @@ -98,14 +114,12 @@ func CheckGitignore(path string) (bool, error) {
return true, nil
}

func WriteGitignore(path string) error {
func writeGitignore(path string) error {
logger.Debug("Writing .gitignore file")
path = filepath.Join(path, ".gitignore")

// Lines to add to .gitignore
linesToAdd := []string{"#Paths added by Azion CLI", ".edge/", ".vulcan"}

// Open the file in append mode, create if not exists
file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
logger.Error("Error opening file", zap.Error(err))
Expand All @@ -123,7 +137,6 @@ func WriteGitignore(path string) error {
}
}

// Ensure all data is written to the file
if err := writer.Flush(); err != nil {
logger.Error("Error flushing writer", zap.Error(err))
return err
Expand Down
264 changes: 264 additions & 0 deletions pkg/github/github_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package github

import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"

"github.com/aziontech/azion-cli/pkg/logger"
"go.uber.org/zap/zapcore"
)

func TestGetVersionGitHub(t *testing.T) {
logger.New(zapcore.DebugLevel)
tests := []struct {
name string
repoName string
wantTag string
statusCode int
response string
wantErr bool
}{
{
name: "not found",
repoName: "test-repo",
wantTag: "",
statusCode: http.StatusNotFound,
response: `{"message": "Not Found"}`,
wantErr: false,
},
{
name: "successful response",
repoName: "azion-cli",
wantTag: "1.30.0",
statusCode: http.StatusOK,
response: `{"tag_name": "1.30.0"}`,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(tt.statusCode)
w.Write([]byte(tt.response))
}))
defer server.Close()

oldURL := ApiURL
ApiURL = server.URL + "/repos/aziontech/%s/releases/tag/1.30.0"
defer func() { ApiURL = oldURL }()

gh := NewGithub()
gh.GetVersionGitHub = getVersionGitHub

gotTag, err := gh.GetVersionGitHub(tt.repoName)
if (err != nil) != tt.wantErr {
t.Errorf("GetVersionGitHub() error = %v, wantErr %v", err, tt.wantErr)
return
}
if gotTag != tt.wantTag {
t.Errorf("GetVersionGitHub() = %v, want %v", gotTag, tt.wantTag)
}
})
}
}

func TestClone(t *testing.T) {
logger.New(zapcore.DebugLevel)
tests := []struct {
name string
url string
wantErr bool
setup func() (string, func())
}{
{
name: "invalid url",
url: "invalid-url",
wantErr: true,
setup: func() (string, func()) {
return t.TempDir(), func() {}
},
},
{
name: "valid url",
url: "https://github.com/aziontech/azion-cli.git",
setup: func() (string, func()) {
// Create a temporary directory
dir := t.TempDir()
// Return the directory path and a cleanup function
return dir, func() {
// Cleanup steps if needed
os.RemoveAll(dir)
}
},
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path, cleanup := tt.setup()
defer cleanup()

gh := NewGithub()
gh.Clone = clone

if err := gh.Clone(tt.url, path); (err != nil) != tt.wantErr {
t.Errorf("Clone() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestGetNameRepo(t *testing.T) {
logger.New(zapcore.DebugLevel)
tests := []struct {
name string
url string
want string
}{
{
name: "with .git",
url: "https://github.com/aziontech/azion-cli.git",
want: "azion-cli",
},
{
name: "without .git",
url: "https://github.com/aziontech/azion-cli",
want: "azion-cli",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gh := NewGithub()
gh.GetNameRepo = getNameRepo

if got := gh.GetNameRepo(tt.url); got != tt.want {
t.Errorf("GetNameRepo() = %v, want %v", got, tt.want)
}
})
}
}

func TestCheckGitignore(t *testing.T) {
logger.New(zapcore.DebugLevel)
tests := []struct {
name string
setup func() string
want bool
wantErr bool
cleanup func(string)
}{
{
name: "exists",
setup: func() string {
path := t.TempDir()
file := filepath.Join(path, ".gitignore")
os.WriteFile(file, []byte(".edge/\n.vulcan\n"), 0644)
return path
},
want: true,
wantErr: false,
cleanup: func(path string) {
os.RemoveAll(path)
},
},
{
name: "does not exist",
setup: func() string {
return t.TempDir()
},
want: false,
wantErr: false,
cleanup: func(path string) {
os.RemoveAll(path)
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := tt.setup()
defer tt.cleanup(path)

gh := NewGithub()
gh.CheckGitignore = checkGitignore

got, err := gh.CheckGitignore(path)
if (err != nil) != tt.wantErr {
t.Errorf("CheckGitignore() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("CheckGitignore() = %v, want %v", got, tt.want)
}
})
}
}

func TestWriteGitignore(t *testing.T) {
logger.New(zapcore.DebugLevel)
tests := []struct {
name string
setup func() string
wantErr bool
wantFile string
cleanup func(string)
}{
{
name: "success",
setup: func() string {
return t.TempDir()
},
wantErr: false,
wantFile: "#Paths added by Azion CLI\n.edge/\n.vulcan\n",
cleanup: func(path string) {
os.RemoveAll(path)
},
},
{
name: "error opening file",
setup: func() string {
path := t.TempDir()
file := filepath.Join(path, ".gitignore")
os.WriteFile(file, []byte{}, 0444) // Create a read-only file
return path
},
wantErr: true,
cleanup: func(path string) {
os.Chmod(filepath.Join(path, ".gitignore"), 0644) // Restore permissions before cleanup
os.RemoveAll(path)
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := tt.setup()
defer tt.cleanup(path)

gh := NewGithub()
gh.WriteGitignore = writeGitignore

err := gh.WriteGitignore(path)
if (err != nil) != tt.wantErr {
t.Errorf("WriteGitignore() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
got, err := os.ReadFile(filepath.Join(path, ".gitignore"))
if err != nil {
t.Errorf("Error reading .gitignore file: %v", err)
return
}
if string(got) != tt.wantFile {
t.Errorf("WriteGitignore() = %v, want %v", string(got), tt.wantFile)
}
}
})
}
}

0 comments on commit ae9f823

Please sign in to comment.