package sandbox import ( "bytes" "encoding/json" "errors" "fmt" "io/fs" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/safedep/dry/usefulerror" "github.com/safedep/pmg/errcodes" pmgsandbox "github.com/safedep/pmg/sandbox" ) func newTestRegistry(t *testing.T, userDir string) registryFactory { t.Helper() return func() (pmgsandbox.ProfileRegistry, error) { opts := []pmgsandbox.RegistryOption{} if userDir != "" { opts = append(opts, pmgsandbox.WithUserProfileDir(userDir)) } return pmgsandbox.NewProfileRegistry(opts...) } } func writeTestUserProfile(t *testing.T, dir, name string) { t.Helper() body := "name: " + name + ` description: user ` + name + ` package_managers: - npm filesystem: allow_read: - /tmp allow_write: - /tmp deny_read: [] deny_write: [] ` require.NoError(t, os.WriteFile(filepath.Join(dir, name+".yml"), []byte(body), 0o644)) } func TestProfileListHuman(t *testing.T) { cmd := newProfileListCommand(newTestRegistry(t, "")) var stdout bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&bytes.Buffer{}) cmd.SetArgs([]string{}) require.NoError(t, cmd.Execute()) out := stdout.String() assert.Contains(t, out, "Sandbox Profiles") assert.Contains(t, out, "npm-restrictive") assert.Contains(t, out, "builtin") } func TestProfileListJSON(t *testing.T) { dir := t.TempDir() writeTestUserProfile(t, dir, "my-custom") cmd := newProfileListCommand(newTestRegistry(t, dir)) var stdout bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&bytes.Buffer{}) cmd.SetArgs([]string{"--json"}) require.NoError(t, cmd.Execute()) var report jsonProfileListReport require.NoError(t, json.Unmarshal(stdout.Bytes(), &report)) require.NotEmpty(t, report.Profiles) var foundBuiltin, foundUser bool for _, p := range report.Profiles { if p.Source == "builtin" { foundBuiltin = true } if p.Source == "user" && p.Name == "my-custom" { foundUser = true assert.NotEmpty(t, p.Path) } } assert.True(t, foundBuiltin) assert.True(t, foundUser) } func TestProfileListShadowedTag(t *testing.T) { dir := t.TempDir() writeTestUserProfile(t, dir, "npm-restrictive") cmd := newProfileListCommand(newTestRegistry(t, dir)) var stdout bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&bytes.Buffer{}) cmd.SetArgs([]string{}) require.NoError(t, cmd.Execute()) assert.Contains(t, stdout.String(), "SHADOWED") } func TestProfileListRegistryFailureReturnsUseful(t *testing.T) { factory := func() (pmgsandbox.ProfileRegistry, error) { return nil, errors.New("boom") } cmd := newProfileListCommand(factory) var stdout, stderr bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&stderr) cmd.SetArgs([]string{}) err := cmd.Execute() require.Error(t, err) usefulErr, ok := usefulerror.AsUsefulError(err) require.True(t, ok) assert.Equal(t, errcodes.Unknown, usefulErr.Code()) assert.Contains(t, err.Error(), "boom") } func TestProfileListRegistryPermissionErrorReturnsPermissionDenied(t *testing.T) { factory := func() (pmgsandbox.ProfileRegistry, error) { return nil, fmt.Errorf("read dir: %w", fs.ErrPermission) } cmd := newProfileListCommand(factory) var stdout, stderr bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&stderr) cmd.SetArgs([]string{}) err := cmd.Execute() require.Error(t, err) usefulErr, ok := usefulerror.AsUsefulError(err) require.True(t, ok) assert.Equal(t, errcodes.PermissionDenied, usefulErr.Code()) } func TestProfileListRejectsUnexpectedArgs(t *testing.T) { cmd := newProfileListCommand(newTestRegistry(t, "")) var stdout, stderr bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&stderr) cmd.SetArgs([]string{"extra"}) err := cmd.Execute() require.Error(t, err) assert.Contains(t, stderr.String(), "unknown command") assert.Contains(t, stdout.String(), "Usage:") assert.Contains(t, stdout.String(), "list [flags]") assert.Contains(t, stdout.String(), "pmg sandbox profile list") }