-
Notifications
You must be signed in to change notification settings - Fork 5
Added unit tests for the go backend #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| package tests | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "encoding/json" | ||
| "net/http" | ||
| "net/http/httptest" | ||
| "testing" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
| "github.com/gittuf/visualizer/go-backend/internal/handlers" | ||
| "github.com/gittuf/visualizer/go-backend/internal/models" | ||
| "github.com/gittuf/visualizer/go-backend/tests/helpers" | ||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func setupRouter() *gin.Engine { | ||
| gin.SetMode(gin.TestMode) | ||
| r := gin.Default() | ||
| r.POST("/commits", handlers.ListCommits) | ||
| r.POST("/metadata", handlers.GetMetadata) | ||
| r.POST("/commits-local", handlers.ListCommitsLocal) | ||
| r.POST("/metadata-local", handlers.GetMetadataLocal) | ||
| return r | ||
| } | ||
|
|
||
| func TestListCommits_Success(t *testing.T) { | ||
| remotePath, _, cleanupRemote := helpers.SetupTestRepo(t) | ||
| defer cleanupRemote() | ||
|
|
||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsRequest{URL: remotePath}) | ||
| req, _ := http.NewRequest("POST", "/commits", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusOK, w.Code) | ||
| var commits []models.Commit | ||
| assert.NoError(t, json.Unmarshal(w.Body.Bytes(), &commits)) | ||
| assert.NotEmpty(t, commits) | ||
| } | ||
|
|
||
| func TestListCommits_MissingURL(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsRequest{}) | ||
| req, _ := http.NewRequest("POST", "/commits", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } | ||
|
|
||
| func TestListCommits_InvalidURL(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsRequest{URL: "invalid-url"}) | ||
| req, _ := http.NewRequest("POST", "/commits", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusInternalServerError, w.Code) | ||
| } | ||
|
|
||
| func TestGetMetadata_Success(t *testing.T) { | ||
| remotePath, commitHash, cleanupRemote := helpers.SetupTestRepo(t) | ||
| defer cleanupRemote() | ||
|
|
||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.MetadataRequest{URL: remotePath, Commit: commitHash, File: "root.json"}) | ||
| req, _ := http.NewRequest("POST", "/metadata", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusOK, w.Code) | ||
| var metadata map[string]interface{} | ||
| assert.NoError(t, json.Unmarshal(w.Body.Bytes(), &metadata)) | ||
| assert.Equal(t, "root", metadata["type"]) | ||
| } | ||
|
|
||
| func TestGetMetadata_MissingURL(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.MetadataRequest{}) | ||
| req, _ := http.NewRequest("POST", "/metadata", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } | ||
|
|
||
| func TestListCommitsLocal_Success(t *testing.T) { | ||
| repoPath, _, cleanup := helpers.SetupTestRepo(t) | ||
| defer cleanup() | ||
|
|
||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsLocalRequest{Path: repoPath}) | ||
| req, _ := http.NewRequest("POST", "/commits-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusOK, w.Code) | ||
| var commits []models.Commit | ||
| assert.NoError(t, json.Unmarshal(w.Body.Bytes(), &commits)) | ||
| assert.NotEmpty(t, commits) | ||
| } | ||
|
|
||
| func TestListCommitsLocal_MissingPath(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsLocalRequest{}) | ||
| req, _ := http.NewRequest("POST", "/commits-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } | ||
|
|
||
| func TestListCommitsLocal_InvalidPath(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.CommitsLocalRequest{Path: "/invalid/path"}) | ||
| req, _ := http.NewRequest("POST", "/commits-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } | ||
|
|
||
| func TestGetMetadataLocal_Success(t *testing.T) { | ||
| repoPath, commitHash, cleanup := helpers.SetupTestRepo(t) | ||
| defer cleanup() | ||
|
|
||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.MetadataLocalRequest{Path: repoPath, Commit: commitHash, File: "root.json"}) | ||
| req, _ := http.NewRequest("POST", "/metadata-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusOK, w.Code) | ||
| var metadata map[string]interface{} | ||
| assert.NoError(t, json.Unmarshal(w.Body.Bytes(), &metadata)) | ||
| assert.Equal(t, "root", metadata["type"]) | ||
| } | ||
|
|
||
| func TestGetMetadataLocal_MissingFields(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.MetadataLocalRequest{}) | ||
| req, _ := http.NewRequest("POST", "/metadata-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } | ||
|
|
||
| func TestGetMetadataLocal_InvalidPath(t *testing.T) { | ||
| r := setupRouter() | ||
| jsonValue, _ := json.Marshal(models.MetadataLocalRequest{Path: "/invalid/path", Commit: "HEAD", File: "root.json"}) | ||
| req, _ := http.NewRequest("POST", "/metadata-local", bytes.NewBuffer(jsonValue)) | ||
| w := httptest.NewRecorder() | ||
| r.ServeHTTP(w, req) | ||
|
|
||
| t.Logf("Response: %d %s", w.Code, w.Body.String()) | ||
| assert.Equal(t, http.StatusBadRequest, w.Code) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| package helpers | ||
|
|
||
| import ( | ||
| "encoding/base64" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/go-git/go-git/v5" | ||
| "github.com/go-git/go-git/v5/plumbing" | ||
| "github.com/go-git/go-git/v5/plumbing/object" | ||
| ) | ||
|
|
||
| // SetupTestRepo creates a temporary git repository with two commits: an initial commit | ||
| // and a second commit containing a gittuf metadata envelope at metadata/root.json, | ||
| // with refs/gittuf/policy pointing at that second commit. | ||
| func SetupTestRepo(t *testing.T) (string, string, func()) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest using gittuf's testing helpers to create a repository here, e.g. copy/use https://github.com/gittuf/gittuf/blob/main/internal/policy/helpers_test.go. Verification of gittuf repos is likely on the roadmap for the visualizer so having the test methods ready to plug in to that would be good. |
||
| t.Helper() | ||
|
|
||
| tempDir, err := os.MkdirTemp("", "gittuf-viz-test-repo-*") | ||
| if err != nil { | ||
| t.Fatalf("Failed to create temp dir: %v", err) | ||
| } | ||
|
|
||
| repo, err := git.PlainInit(tempDir, false) | ||
| if err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to init git repo: %v", err) | ||
| } | ||
|
|
||
| w, err := repo.Worktree() | ||
| if err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to get worktree: %v", err) | ||
| } | ||
|
|
||
| dummyFile := filepath.Join(tempDir, "README.md") | ||
| if err := os.WriteFile(dummyFile, []byte("# Test Repo"), 0600); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to write dummy file: %v", err) | ||
| } | ||
| if _, err := w.Add("README.md"); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to add file: %v", err) | ||
| } | ||
| if _, err := w.Commit("Initial commit", &git.CommitOptions{ | ||
| Author: &object.Signature{Name: "Test User", Email: "test@example.com", When: time.Now()}, | ||
| }); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to commit: %v", err) | ||
| } | ||
|
|
||
| rootJSON := `{"type":"root", "expires":"2030-01-01T00:00:00Z"}` | ||
| rootB64 := base64.StdEncoding.EncodeToString([]byte(rootJSON)) | ||
| envelope := fmt.Sprintf(`{"payload": "%s", "signatures": []}`, rootB64) | ||
|
|
||
| metadataDir := filepath.Join(tempDir, "metadata") | ||
| if err := os.MkdirAll(metadataDir, 0750); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to create metadata dir: %v", err) | ||
| } | ||
|
|
||
| policyFile := filepath.Join(metadataDir, "root.json") | ||
| if err := os.WriteFile(policyFile, []byte(envelope), 0600); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to write policy file: %v", err) | ||
| } | ||
| if _, err := w.Add("metadata/root.json"); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to add policy file: %v", err) | ||
| } | ||
|
|
||
| commitHash, err := w.Commit("Add root.json", &git.CommitOptions{ | ||
| Author: &object.Signature{Name: "Gittuf Admin", Email: "admin@gittuf.com", When: time.Now()}, | ||
| }) | ||
| if err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to commit policy: %v", err) | ||
| } | ||
|
|
||
| ref := plumbing.NewHashReference("refs/gittuf/policy", commitHash) | ||
| if err := repo.Storer.SetReference(ref); err != nil { | ||
| os.RemoveAll(tempDir) | ||
| t.Fatalf("Failed to set policy ref: %v", err) | ||
| } | ||
|
|
||
| t.Logf("Test repo: path=%s policy_commit=%s", tempDir, commitHash) | ||
|
|
||
| return tempDir, commitHash.String(), func() { os.RemoveAll(tempDir) } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package tests | ||
|
|
||
| import ( | ||
| "os" | ||
| "testing" | ||
|
|
||
| "github.com/gittuf/visualizer/go-backend/internal/logger" | ||
| ) | ||
|
|
||
| // TestMain sets up the test environment and initializes the logger. | ||
| func TestMain(m *testing.M) { | ||
| logger.Initialize() | ||
| code := m.Run() | ||
| logger.Sync() | ||
| os.Exit(code) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a listing/description file that you intended to add?