github.com/supabase/cli@v1.168.1/internal/bootstrap/bootstrap_test.go (about)

     1  package bootstrap
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/jackc/pgconn"
     9  	"github.com/joho/godotenv"
    10  	"github.com/spf13/afero"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/supabase/cli/internal/utils/flags"
    14  	"github.com/supabase/cli/pkg/api"
    15  )
    16  
    17  func TestSuggestAppStart(t *testing.T) {
    18  	t.Run("suggest npm", func(t *testing.T) {
    19  		cwd, err := os.Getwd()
    20  		require.NoError(t, err)
    21  		// Run test
    22  		suggestion := suggestAppStart(cwd, "npm ci && npm run dev")
    23  		// Check error
    24  		assert.Equal(t, "To start your app:\n  npm ci && npm run dev", suggestion)
    25  	})
    26  
    27  	t.Run("suggest cd", func(t *testing.T) {
    28  		cwd, err := os.Getwd()
    29  		require.NoError(t, err)
    30  		// Run test
    31  		suggestion := suggestAppStart(filepath.Dir(cwd), "npm ci && npm run dev")
    32  		// Check error
    33  		expected := "To start your app:"
    34  		expected += "\n  cd " + filepath.Base(cwd)
    35  		expected += "\n  npm ci && npm run dev"
    36  		assert.Equal(t, expected, suggestion)
    37  	})
    38  
    39  	t.Run("ignore relative path", func(t *testing.T) {
    40  		// Run test
    41  		suggestion := suggestAppStart(".", "supabase start")
    42  		// Check error
    43  		assert.Equal(t, "To start your app:\n  supabase start", suggestion)
    44  	})
    45  }
    46  
    47  func TestWriteEnv(t *testing.T) {
    48  	var apiKeys = []api.ApiKeyResponse{{
    49  		ApiKey: "anonkey",
    50  		Name:   "anon",
    51  	}, {
    52  		ApiKey: "servicekey",
    53  		Name:   "service_role",
    54  	}}
    55  
    56  	var dbConfig = pgconn.Config{
    57  		Host:     "db.supabase.co",
    58  		Port:     5432,
    59  		User:     "admin",
    60  		Password: "password",
    61  		Database: "postgres",
    62  	}
    63  
    64  	t.Run("writes .env", func(t *testing.T) {
    65  		flags.ProjectRef = "testing"
    66  		// Setup in-memory fs
    67  		fsys := afero.NewMemMapFs()
    68  		// Run test
    69  		err := writeDotEnv(apiKeys, dbConfig, fsys)
    70  		// Check error
    71  		assert.NoError(t, err)
    72  		env, err := afero.ReadFile(fsys, ".env")
    73  		assert.NoError(t, err)
    74  		assert.Equal(t, `POSTGRES_URL="postgresql://admin:password@db.supabase.co:6543/postgres?connect_timeout=10"
    75  SUPABASE_ANON_KEY="anonkey"
    76  SUPABASE_SERVICE_ROLE_KEY="servicekey"
    77  SUPABASE_URL="https://testing.supabase.co"`, string(env))
    78  	})
    79  
    80  	t.Run("merges with .env.example", func(t *testing.T) {
    81  		flags.ProjectRef = "testing"
    82  		// Setup in-memory fs
    83  		fsys := afero.NewMemMapFs()
    84  		example, err := godotenv.Marshal(map[string]string{
    85  			POSTGRES_PRISMA_URL:           "example",
    86  			POSTGRES_URL_NON_POOLING:      "example",
    87  			POSTGRES_USER:                 "example",
    88  			POSTGRES_HOST:                 "example",
    89  			POSTGRES_PASSWORD:             "example",
    90  			POSTGRES_DATABASE:             "example",
    91  			NEXT_PUBLIC_SUPABASE_ANON_KEY: "example",
    92  			NEXT_PUBLIC_SUPABASE_URL:      "example",
    93  			"no_match":                    "example",
    94  			SUPABASE_SERVICE_ROLE_KEY:     "example",
    95  			SUPABASE_ANON_KEY:             "example",
    96  			SUPABASE_URL:                  "example",
    97  			POSTGRES_URL:                  "example",
    98  		})
    99  		require.NoError(t, err)
   100  		require.NoError(t, afero.WriteFile(fsys, ".env.example", []byte(example), 0644))
   101  		// Run test
   102  		err = writeDotEnv(apiKeys, dbConfig, fsys)
   103  		// Check error
   104  		assert.NoError(t, err)
   105  		env, err := afero.ReadFile(fsys, ".env")
   106  		assert.NoError(t, err)
   107  		assert.Equal(t, `NEXT_PUBLIC_SUPABASE_ANON_KEY="anonkey"
   108  NEXT_PUBLIC_SUPABASE_URL="https://testing.supabase.co"
   109  POSTGRES_DATABASE="postgres"
   110  POSTGRES_HOST="db.supabase.co"
   111  POSTGRES_PASSWORD="password"
   112  POSTGRES_PRISMA_URL="postgresql://admin:password@db.supabase.co:6543/postgres?connect_timeout=10"
   113  POSTGRES_URL="postgresql://admin:password@db.supabase.co:6543/postgres?connect_timeout=10"
   114  POSTGRES_URL_NON_POOLING="postgresql://admin:password@db.supabase.co:5432/postgres?connect_timeout=10"
   115  POSTGRES_USER="admin"
   116  SUPABASE_ANON_KEY="anonkey"
   117  SUPABASE_SERVICE_ROLE_KEY="servicekey"
   118  SUPABASE_URL="https://testing.supabase.co"
   119  no_match="example"`, string(env))
   120  	})
   121  
   122  	t.Run("throws error on malformed example", func(t *testing.T) {
   123  		// Setup in-memory fs
   124  		fsys := afero.NewMemMapFs()
   125  		require.NoError(t, afero.WriteFile(fsys, ".env.example", []byte("!="), 0644))
   126  		// Run test
   127  		err := writeDotEnv(nil, dbConfig, fsys)
   128  		// Check error
   129  		assert.ErrorContains(t, err, `unexpected character "!" in variable name near "!="`)
   130  	})
   131  
   132  	t.Run("throws error on permission denied", func(t *testing.T) {
   133  		// Setup in-memory fs
   134  		fsys := afero.NewMemMapFs()
   135  		// Run test
   136  		err := writeDotEnv(nil, dbConfig, afero.NewReadOnlyFs(fsys))
   137  		// Check error
   138  		assert.ErrorIs(t, err, os.ErrPermission)
   139  	})
   140  }