Skip to content

Commit

Permalink
chore: update unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Jan 29, 2024
1 parent a96bcdf commit ab57f64
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 70 deletions.
21 changes: 2 additions & 19 deletions cmd/unlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,14 @@ var (
unlinkCmd = &cobra.Command{
GroupID: groupLocalDev,
Use: "unlink",
Short: "Unlink to a Supabase project",
PreRunE: func(cmd *cobra.Command, args []string) error {
return cmd.MarkFlagRequired("project-ref")
},
Short: "Unlink a Supabase project",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt)
fsys := afero.NewOsFs()
if err := unlink.PreRun(projectRef, fsys); err != nil {
return err
}
if len(projectRef) == 0 {
if err := PromptProjectRef(ctx); err != nil {
return err
}
}
return unlink.Run(ctx, projectRef, fsys)
},
PostRunE: func(cmd *cobra.Command, args []string) error {
return unlink.PostRun("", os.Stdout, afero.NewOsFs())
return unlink.Run(ctx, afero.NewOsFs())
},
}
)

func init() {
flags := unlinkCmd.Flags()
flags.StringVar(&projectRef, "project-ref", "", "Project ref of the Supabase project.")
rootCmd.AddCommand(unlinkCmd)
}
47 changes: 16 additions & 31 deletions internal/unlink/unlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,34 @@ package unlink
import (
"context"
"fmt"
"io"
"os"

"github.com/go-errors/errors"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/credentials"
"github.com/supabase/cli/internal/utils/flags"
"github.com/zalando/go-keyring"
)

func PreRun(projectRef string, fsys afero.Fs) error {
return utils.LoadConfigFS(fsys)
}
func Run(ctx context.Context, fsys afero.Fs) error {
projectRef, err := flags.LoadProjectRef(fsys)
if err != nil {
return err
}

func Run(ctx context.Context, projectRef string, fsys afero.Fs) error {
fmt.Fprintln(os.Stderr, "Unlinking project:", projectRef)
// Remove temp directory
if err := removeTempDir(fsys); err != nil {
return err
if err := fsys.RemoveAll(utils.TempDir); err != nil {
return errors.Errorf("failed to remove temp directory: %w", err)
}
// Remove linked credentials
if err := removeLinkedCredentials(projectRef); err != nil {
if err := credentials.Delete(projectRef); err != nil &&
!errors.Is(err, credentials.ErrNotSupported) &&
!errors.Is(err, keyring.ErrNotFound) {
return err
}
fmt.Println("Successfully unlinked project.")
return nil
}

func PostRun(projectRef string, stdout io.Writer, fsys afero.Fs) error {
fmt.Fprintln(stdout, "Finished "+utils.Aqua("supabase unlink")+".")
return nil
}

// removeLinkedCredentials removes the database password associated with the projectRef
func removeLinkedCredentials(projectRef string) error {
fmt.Printf("Removing credentials for project %s...\n", projectRef)
if err := credentials.Set(projectRef, ""); err != nil {
return fmt.Errorf("failed to remove credentials for project '%s': %w", projectRef, err)
}
fmt.Println("Credentials for project", projectRef, "have been successfully removed.")
return nil
}

func removeTempDir(fsys afero.Fs) error {
tempDir := utils.TempDir
if err := fsys.RemoveAll(tempDir); err != nil {
return fmt.Errorf("failed to remove temp directory %s: %w", tempDir, err)
}
fmt.Fprintln(os.Stdout, "Finished "+utils.Aqua("supabase unlink")+".")
return nil
}
62 changes: 42 additions & 20 deletions internal/unlink/unlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,67 @@ package unlink

import (
"context"
"os"
"testing"

"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/supabase/cli/internal/testing/apitest"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/credentials"
"github.com/zalando/go-keyring"
)

func TestUnlinkCommand(t *testing.T) {
keyring.MockInit()
project := "test-project"
password := "test-password"
project := apitest.RandomProjectRef()

t.Run("unlink valid project", func(t *testing.T) {
t.Run("unlinks project", func(t *testing.T) {
// Setup in-memory fs
// Set up a mock filesystem or a temp directory
fs := afero.NewMemMapFs() // or setup a real temp directory
err := afero.WriteFile(fs, "supabase/.temp/project-ref", []byte(project), 0644)
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ProjectRefPath, []byte(project), 0644))
// Save database password
require.NoError(t, credentials.Set(project, "test"))
// Run test
err := Run(context.Background(), fsys)
// Check error
assert.NoError(t, err)
// Validate file does not exist
exists, err := afero.Exists(fsys, utils.ProjectRefPath)
assert.NoError(t, err)
assert.False(t, exists)
// Check credentials does not exist
_, err = credentials.Get(project)
assert.ErrorIs(t, err, keyring.ErrNotFound)
})

// Save database password
err = credentials.Set(project, password)
t.Run("unlinks project without credentials", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ProjectRefPath, []byte(project), 0644))
// Run test
err := Run(context.Background(), fsys)
// Check error
assert.NoError(t, err)
// Run unlink test
err = Run(context.Background(), project, fs)
})

t.Run("throws error if not linked", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
// Run test
err := Run(context.Background(), fsys)
// Check error
assert.NoError(t, err)
// Validate file does not exist
_, err = afero.ReadFile(fs, utils.ProjectRefPath)
assert.Error(t, err)
// check credentials
// FIXME: only works this way because of the global state
// of credentials
content, err := credentials.Get(project)
assert.Equal(t, "", content)
assert.NoError(t, err)
assert.ErrorIs(t, err, utils.ErrNotLinked)
})

t.Run("throws error on permission denied", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ProjectRefPath, []byte(project), 0644))
// Run test
err := Run(context.Background(), afero.NewReadOnlyFs(fsys))
// Check error
assert.ErrorIs(t, err, os.ErrPermission)
})
}

0 comments on commit ab57f64

Please sign in to comment.