Borg/cmd/all_test.go
google-labs-jules[bot] ed38992830 feat: Collection manifest generation
This commit introduces the ability to generate a manifest file that lists the contents of a collection, including metadata such as file size, SHA256 hash, and file type statistics.

The manifest can be generated in three ways:
- During collection, by using the `--manifest` flag with the `collect all` command.
- From an existing archive, by using the new `borg manifest` command.
- As a public, unencrypted header in a `.stim` file, by using the `--public-manifest` flag with the `compile` command.

This feature is useful for inspecting the contents of large or encrypted archives without having to extract them first.

Co-authored-by: Snider <631881+Snider@users.noreply.github.com>
2026-02-02 00:47:56 +00:00

176 lines
5 KiB
Go

package cmd
import (
"bytes"
"context"
"io"
"net/http"
"os"
"path/filepath"
"testing"
"github.com/Snider/Borg/pkg/datanode"
"github.com/Snider/Borg/pkg/github"
"github.com/Snider/Borg/pkg/mocks"
)
func TestAllCmd_Good(t *testing.T) {
// Setup mock HTTP client for GitHub API
mockGithubClient := mocks.NewMockClient(map[string]*http.Response{
"https://api.github.com/users/testuser/repos": {
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(bytes.NewBufferString(`[{"clone_url": "https://github.com/testuser/repo1.git"}]`)),
},
})
oldNewAuthenticatedClient := github.NewAuthenticatedClient
github.NewAuthenticatedClient = func(ctx context.Context) *http.Client {
return mockGithubClient
}
defer func() {
github.NewAuthenticatedClient = oldNewAuthenticatedClient
}()
// Setup mock Git cloner
mockCloner := &mocks.MockGitCloner{
DN: datanode.New(),
Err: nil,
}
oldCloner := GitCloner
GitCloner = mockCloner
defer func() {
GitCloner = oldCloner
}()
rootCmd := NewRootCmd()
rootCmd.AddCommand(GetAllCmd())
// Execute command
out := filepath.Join(t.TempDir(), "out")
_, err := executeCommand(rootCmd, "all", "https://github.com/testuser", "--output", out)
if err != nil {
t.Fatalf("all command failed: %v", err)
}
}
func TestAllCmd_Bad(t *testing.T) {
// Setup mock HTTP client to return an error
mockGithubClient := mocks.NewMockClient(map[string]*http.Response{
"https://api.github.com/users/baduser/repos": {
StatusCode: http.StatusNotFound,
Status: "404 Not Found",
Body: io.NopCloser(bytes.NewBufferString(`{"message": "Not Found"}`)),
},
"https://api.github.com/orgs/baduser/repos": {
StatusCode: http.StatusNotFound,
Status: "404 Not Found",
Body: io.NopCloser(bytes.NewBufferString(`{"message": "Not Found"}`)),
},
})
oldNewAuthenticatedClient := github.NewAuthenticatedClient
github.NewAuthenticatedClient = func(ctx context.Context) *http.Client {
return mockGithubClient
}
defer func() {
github.NewAuthenticatedClient = oldNewAuthenticatedClient
}()
rootCmd := NewRootCmd()
rootCmd.AddCommand(GetAllCmd())
// Execute command
out := filepath.Join(t.TempDir(), "out")
_, err := executeCommand(rootCmd, "all", "https://github.com/baduser", "--output", out)
if err == nil {
t.Fatal("expected an error, but got none")
}
}
func TestAllCmd_Ugly(t *testing.T) {
t.Run("User with no repos", func(t *testing.T) {
// Setup mock HTTP client for a user with no repos
mockGithubClient := mocks.NewMockClient(map[string]*http.Response{
"https://api.github.com/users/emptyuser/repos": {
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(bytes.NewBufferString(`[]`)),
},
})
oldNewAuthenticatedClient := github.NewAuthenticatedClient
github.NewAuthenticatedClient = func(ctx context.Context) *http.Client {
return mockGithubClient
}
defer func() {
github.NewAuthenticatedClient = oldNewAuthenticatedClient
}()
rootCmd := NewRootCmd()
rootCmd.AddCommand(GetAllCmd())
// Execute command
out := filepath.Join(t.TempDir(), "out")
_, err := executeCommand(rootCmd, "all", "https://github.com/emptyuser", "--output", out)
if err != nil {
t.Fatalf("all command failed for user with no repos: %v", err)
}
})
}
func TestAllCmd_WithManifest_Good(t *testing.T) {
// Setup mock HTTP client for GitHub API
mockGithubClient := mocks.NewMockClient(map[string]*http.Response{
"https://api.github.com/users/testuser/repos": {
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(bytes.NewBufferString(`[{"clone_url": "https://github.com/testuser/repo1.git"}]`)),
},
})
oldNewAuthenticatedClient := github.NewAuthenticatedClient
github.NewAuthenticatedClient = func(ctx context.Context) *http.Client {
return mockGithubClient
}
t.Cleanup(func() {
github.NewAuthenticatedClient = oldNewAuthenticatedClient
})
// Setup mock Git cloner
mockCloner := &mocks.MockGitCloner{
DN: datanode.New(),
Err: nil,
}
mockCloner.DN.AddData("README.md", []byte("# repo1"))
oldAllCloner := allCloner
allCloner = mockCloner
t.Cleanup(func() {
allCloner = oldAllCloner
})
rootCmd := NewRootCmd()
rootCmd.AddCommand(GetAllCmd())
// Execute command
out := filepath.Join(t.TempDir(), "out.dat")
_, err := executeCommand(rootCmd, "all", "https://github.com/testuser", "--output", out, "--manifest")
if err != nil {
t.Fatalf("all command failed: %v", err)
}
// Verify MANIFEST.json exists
data, err := os.ReadFile(out)
if err != nil {
t.Fatalf("failed to read output file: %v", err)
}
dn, err := datanode.FromTar(data)
if err != nil {
t.Fatalf("failed to create datanode from tar: %v", err)
}
exists, err := dn.Exists("MANIFEST.json")
if err != nil {
t.Fatalf("failed to check for manifest: %v", err)
}
if !exists {
t.Fatal("MANIFEST.json not found in the output datanode")
}
}