github.com/supabase/cli@v1.168.1/internal/utils/flags/project_ref_test.go (about)

     1  package flags
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/go-errors/errors"
    10  	"github.com/spf13/afero"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/supabase/cli/internal/testing/apitest"
    14  	"github.com/supabase/cli/internal/testing/fstest"
    15  	"github.com/supabase/cli/internal/utils"
    16  	"github.com/supabase/cli/pkg/api"
    17  	"gopkg.in/h2non/gock.v1"
    18  )
    19  
    20  func TestProjectRef(t *testing.T) {
    21  	t.Run("validates cmd flag", func(t *testing.T) {
    22  		ProjectRef = "invalid"
    23  		// Setup in-memory fs
    24  		fsys := afero.NewMemMapFs()
    25  		// Run test
    26  		err := ParseProjectRef(context.Background(), fsys)
    27  		// Check error
    28  		assert.Error(t, err, utils.ErrInvalidRef)
    29  	})
    30  
    31  	t.Run("loads from linked", func(t *testing.T) {
    32  		ProjectRef = ""
    33  		// Setup in-memory fs
    34  		fsys := afero.NewMemMapFs()
    35  		// Setup valid project ref
    36  		project := apitest.RandomProjectRef()
    37  		err := afero.WriteFile(fsys, utils.ProjectRefPath, []byte(project), 0644)
    38  		require.NoError(t, err)
    39  		// Run test
    40  		err = ParseProjectRef(context.Background(), fsys)
    41  		// Check error
    42  		assert.NoError(t, err)
    43  	})
    44  
    45  	t.Run("throws error on read failure", func(t *testing.T) {
    46  		ProjectRef = ""
    47  		// Setup in-memory fs
    48  		fsys := &fstest.OpenErrorFs{DenyPath: utils.ProjectRefPath}
    49  		// Run test
    50  		err := ParseProjectRef(context.Background(), fsys)
    51  		// Check error
    52  		assert.ErrorIs(t, err, os.ErrPermission)
    53  	})
    54  
    55  	t.Run("throws error if all fail", func(t *testing.T) {
    56  		ProjectRef = ""
    57  		// Setup in-memory fs
    58  		fsys := afero.NewMemMapFs()
    59  		// Run test
    60  		err := ParseProjectRef(context.Background(), fsys)
    61  		// Check error
    62  		assert.ErrorIs(t, err, utils.ErrNotLinked)
    63  	})
    64  }
    65  
    66  func TestProjectPrompt(t *testing.T) {
    67  	// Setup valid access token
    68  	token := apitest.RandomAccessToken(t)
    69  	t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
    70  
    71  	t.Run("validates prompt input", func(t *testing.T) {
    72  		// Setup mock api
    73  		defer gock.OffAll()
    74  		gock.New(utils.DefaultApiHost).
    75  			Get("/v1/projects").
    76  			Reply(http.StatusOK).
    77  			JSON([]api.V1ProjectResponse{{
    78  				Id:             "test-project",
    79  				Name:           "My Project",
    80  				OrganizationId: "test-org",
    81  			}})
    82  		// Run test
    83  		err := PromptProjectRef(context.Background(), "")
    84  		// Check error
    85  		assert.ErrorContains(t, err, "failed to prompt choice:")
    86  		assert.Empty(t, apitest.ListUnmatchedRequests())
    87  	})
    88  
    89  	t.Run("throws error on network failure", func(t *testing.T) {
    90  		errNetwork := errors.New("network error")
    91  		// Setup mock api
    92  		defer gock.OffAll()
    93  		gock.New(utils.DefaultApiHost).
    94  			Get("/v1/projects").
    95  			ReplyError(errNetwork)
    96  		// Run test
    97  		err := PromptProjectRef(context.Background(), "")
    98  		// Check error
    99  		assert.ErrorIs(t, err, errNetwork)
   100  	})
   101  
   102  	t.Run("throws error on service unavailable", func(t *testing.T) {
   103  		// Setup mock api
   104  		defer gock.OffAll()
   105  		gock.New(utils.DefaultApiHost).
   106  			Get("/v1/projects").
   107  			Reply(http.StatusServiceUnavailable)
   108  		// Run test
   109  		err := PromptProjectRef(context.Background(), "")
   110  		// Check error
   111  		assert.ErrorContains(t, err, "Unexpected error retrieving projects:")
   112  	})
   113  }