From 3db2ca2566cdd2bcfa9dbeab94ea14051f5b9c92 Mon Sep 17 00:00:00 2001 From: Slug-Boi Date: Wed, 9 Apr 2025 20:00:37 +0200 Subject: [PATCH] test: extend test coverage by adding more utils tests --- src/cmd/utils/util_test.go | 269 +++++++++++++++++++++++++++++++++++-- 1 file changed, 258 insertions(+), 11 deletions(-) diff --git a/src/cmd/utils/util_test.go b/src/cmd/utils/util_test.go index 2494836..532c371 100644 --- a/src/cmd/utils/util_test.go +++ b/src/cmd/utils/util_test.go @@ -2,7 +2,11 @@ package utils_test import ( "encoding/json" + "fmt" + "io" + "net/http" "os" + "strings" "testing" "github.com/Slug-Boi/cocommit/src/cmd/utils" @@ -47,7 +51,7 @@ func teardown() { } // Author tests BEGIN -func Test_FindAuthorFile(t* testing.T) { +func Test_FindAuthorFile(t *testing.T) { setup() defer teardown() // Test Find_authorfile @@ -88,9 +92,9 @@ func Test_CreateAuthor(t *testing.T) { Shortname: "epic", Longname: "Test", Username: "TestUser", - Email: "bestemailever@github.io", - Ex: false, - Groups: []string{"test"}, + Email: "bestemailever@github.io", + Ex: false, + Groups: []string{"test"}, } utils.CreateAuthor(author) // Check if author was added @@ -105,7 +109,7 @@ func Test_CreateAuthor(t *testing.T) { if err != nil { t.Errorf("Error reading file: %v", err) } - + //unmarshal the data var authors utils.Author err = json.Unmarshal(author_data, &authors) @@ -117,7 +121,6 @@ func Test_CreateAuthor(t *testing.T) { } } - // Author tests END // User tests BEGIN @@ -131,6 +134,56 @@ func Test_DefineUsers(t *testing.T) { } } +func Test_DefineUsersMultipleGroups(t *testing.T) { + setup() + defer teardown() + + utils.Define_users("author_file_test") + utils.CreateAuthor(utils.User{ + Shortname: "epic", + Longname: "Test", + Username: "TestUser", + Email: "dontcare", + Ex: false, + Groups: []string{"gr1"}, + }) + + if len(utils.Users) != 6 { + t.Errorf("Define_users() = %v; want 6", len(utils.Users)) + } + if len(utils.Groups["gr1"]) != 2 { + t.Errorf("Define_users() = %v; want 2", len(utils.Groups["gr1"])) + } +} + +func Test_DefineUsersPanicOnMissingFile(t *testing.T) { + // Test Define_users panic on missing file + defer func() { + if r := recover(); r == nil { + t.Errorf("Define_users() did not panic on missing file") + } + }() + utils.Define_users("non_existent_file") +} + +func Test_DefineUsersPanicOnInvalidJSON(t *testing.T) { + setup() + defer teardown() + + // Create a file with invalid JSON + invalidJSON := `{"Authors": { "invalid": "data"` + os.WriteFile("invalid_author_file_test", []byte(invalidJSON), 0644) + defer os.Remove("invalid_author_file_test") + + // Test Define_users panic on invalid JSON + defer func() { + if r := recover(); r == nil { + t.Errorf("Define_users() did not panic on invalid JSON") + } + }() + utils.Define_users("invalid_author_file_test") +} + func Test_RemoveUser(t *testing.T) { setup() defer teardown() @@ -138,7 +191,7 @@ func Test_RemoveUser(t *testing.T) { utils.Define_users("author_file_test") utils.RemoveUser("te") - + if len(utils.Users) != 2 { t.Errorf("RemoveUser() = %v; want 2", len(utils.Users)) } @@ -158,17 +211,53 @@ func Test_TempAddUser(t *testing.T) { if len(utils.Users) != 5 { t.Errorf("TempAddUser() = %v; want 5", len(utils.Users)) } - + if _, ok := utils.Users["temp"]; !ok { t.Errorf("TempAddUser() did not add user") } - + } + +func Test_ContainsUser(t *testing.T) { + setup() + defer teardown() + // Test ContainsUser + utils.Define_users("author_file_test") + user := utils.Users["te"] + userList := make([]utils.User, 0, len(utils.Users)) + for _, u := range utils.Users { + userList = append(userList, u) + } + if !utils.ContainsUser(userList, user) { + t.Errorf("ContainsUser() = %v; want true", false) + } + + if utils.ContainsUser(userList, utils.User{}) { + t.Errorf("ContainsUser() = %v; want false", true) + } +} + +func Test_CheckUserFields(t *testing.T) { + setup() + defer teardown() + // Test CheckUserFields + utils.Define_users("author_file_test") + user := utils.Users["te"] + if !utils.CheckUserFields(user) { + t.Errorf("CheckUserFields() = %v; want true", false) + } + + emptyUser := utils.User{} + if utils.CheckUserFields(emptyUser) { + t.Errorf("CheckUserFields() = %v; want false", true) + } +} + // User tests END // Commit tests BEGIN -func Test_Commit(t* testing.T) { +func Test_Commit(t *testing.T) { setup() defer teardown() utils.Define_users("author_file_test") @@ -180,6 +269,66 @@ func Test_Commit(t* testing.T) { t.Errorf("Commit() = %v; want Test commit message\n", commit) } } + +func Test_CommitWithAllAuthors(t *testing.T) { + setup() + defer teardown() + utils.Define_users("author_file_test") + + // Test Commit with "all" authors + authors := []string{"all"} + message := "Test commit message with all authors" + commit := utils.Commit(message, authors) + + // Verify that all authors are included in the commit message + for _, user := range utils.Users { + coAuthorLine := fmt.Sprintf("Co-authored-by: %s <%s>", user.Username, user.Email) + if !strings.Contains(commit, coAuthorLine) { + t.Errorf("Commit() missing co-author line: %v", coAuthorLine) + } + } +} + +func Test_CommitWithGroupAuthors(t *testing.T) { + setup() + defer teardown() + utils.Define_users("author_file_test") + + // Test Commit with a group of authors + authors := []string{"gr1"} + message := "Test commit message with group authors" + commit := utils.Commit(message, authors) + + // Verify that all group members are included in the commit message + for _, user := range utils.Groups["gr1"] { + coAuthorLine := fmt.Sprintf("Co-authored-by: %s <%s>", user.Username, user.Email) + if !strings.Contains(commit, coAuthorLine) { + t.Errorf("Commit() missing co-author line for group member: %v", coAuthorLine) + } + } +} + +func Test_CommitWithInvalidGroup(t *testing.T) { + setup() + defer teardown() + + // Reset utils.Users and utils.Groups to avoid interference from other tests + utils.Users = make(map[string]utils.User) + utils.Groups = make(map[string][]utils.User) + + utils.Define_users("author_file_test") + + // Test Commit with an invalid group + authors := []string{"invalid_group"} + message := "Test commit message with invalid group" + commit := utils.Commit(message, authors) + + // Verify that no co-author lines are added for the invalid group + if strings.Contains(commit, "Co-authored-by:") { + t.Errorf("Commit() should not include co-author lines for an invalid group msg: %s ", commit) + } +} + // Commit tests END // Github tests BEGIN @@ -207,5 +356,103 @@ func Test_FetchGHProfile(t *testing.T) { t.Errorf("FetchGithubProfile() = %v; want 0", len(profile.Groups)) } } -// Github tests END +func Test_FetchGHProfilePanicOnRequestError(t *testing.T) { + // Test FetchGithubProfile panic on HTTP request error + defer func() { + if r := recover(); r == nil { + t.Errorf("FetchGithubProfile() did not panic on HTTP request error") + } + }() + + // Simulate an invalid URL by using an invalid username + utils.FetchGithubProfile("invalid_username_with_special_characters_@#$") +} + +func Test_FetchGHProfilePanicOnInvalidJSON(t *testing.T) { + // Test FetchGithubProfile panic on invalid JSON response + defer func() { + if r := recover(); r == nil { + t.Errorf("FetchGithubProfile() did not panic on invalid JSON response") + } + }() + + // Mock the HTTP response to return invalid JSON + http.DefaultClient = &http.Client{ + Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"invalid_json":`)), + }, nil + }), + } + + utils.FetchGithubProfile("valid_username") +} + +func Test_FetchGHProfilePanicOnHTTPGetError(t *testing.T) { + // Test FetchGithubProfile panic on HTTP GET error + defer func() { + if r := recover(); r == nil { + t.Errorf("FetchGithubProfile() did not panic on HTTP GET error") + } + }() + + // Mock the HTTP client to simulate an error during the GET request + http.DefaultClient = &http.Client{ + Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { + return nil, fmt.Errorf("simulated HTTP GET error") + }), + } + + utils.FetchGithubProfile("any_username") +} + +type roundTripperFunc func(req *http.Request) (*http.Response, error) + +func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return f(req) +} + +func Test_FetchGHProfileHTTP(t *testing.T) { + setup() + defer teardown() + + // Mock the HTTP client to simulate a successful response + mockResponse := `{ + "login": "Slug-Boi", + "name": "Theis", + "email": "", + "bio": "Test bio" + }` + http.DefaultClient = &http.Client{ + Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { + if req.URL.String() != "https://api.github.com/users/Slug-Boi" { + t.Errorf("Unexpected URL: %v", req.URL.String()) + } + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(mockResponse)), + }, nil + }), + } + + // Alias the `gh` command to an error to ensure the GitHub CLI is not used + os.Setenv("PATH", "/nonexistent") + + // Test FetchGithubProfile using HTTP request + profile := utils.FetchGithubProfile("Slug-Boi") + if profile.Username != "Slug-Boi" { + t.Errorf("FetchGithubProfile() = %v; want Slug-Boi", profile.Username) + } + if profile.Longname != "Theis" { + t.Errorf("FetchGithubProfile() = %v; want Theis", profile.Longname) + } + if profile.Email != "" { + t.Errorf("FetchGithubProfile() = %v; want empty email", profile.Email) + } +} + + + +// Github tests END