github.com/supabase/cli@v1.168.1/internal/init/init_test.go (about) 1 package init 2 3 import ( 4 "encoding/json" 5 "os" 6 "testing" 7 8 "github.com/spf13/afero" 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 "github.com/supabase/cli/internal/testing/fstest" 12 "github.com/supabase/cli/internal/utils" 13 ) 14 15 func TestInitCommand(t *testing.T) { 16 t.Run("creates config file", func(t *testing.T) { 17 // Setup in-memory fs 18 fsys := &afero.MemMapFs{} 19 require.NoError(t, fsys.Mkdir(".git", 0755)) 20 // Run test 21 assert.NoError(t, Run(fsys, nil, nil, utils.InitParams{})) 22 // Validate generated config.toml 23 exists, err := afero.Exists(fsys, utils.ConfigPath) 24 assert.NoError(t, err) 25 assert.True(t, exists) 26 // Validate generated .gitignore 27 exists, err = afero.Exists(fsys, utils.GitIgnorePath) 28 assert.NoError(t, err) 29 assert.True(t, exists) 30 // Validate generated seed.sql 31 exists, err = afero.Exists(fsys, utils.SeedDataPath) 32 assert.NoError(t, err) 33 assert.True(t, exists) 34 // Validate vscode settings file isn't generated 35 exists, err = afero.Exists(fsys, settingsPath) 36 assert.NoError(t, err) 37 assert.False(t, exists) 38 exists, err = afero.Exists(fsys, extensionsPath) 39 assert.NoError(t, err) 40 assert.False(t, exists) 41 // Validate intellij settings file isn't generated 42 exists, err = afero.Exists(fsys, denoPath) 43 assert.NoError(t, err) 44 assert.False(t, exists) 45 }) 46 47 t.Run("throws error when config file exists", func(t *testing.T) { 48 // Setup in-memory fs 49 fsys := &afero.MemMapFs{} 50 _, err := fsys.Create(utils.ConfigPath) 51 require.NoError(t, err) 52 // Run test 53 assert.Error(t, Run(fsys, nil, nil, utils.InitParams{})) 54 }) 55 56 t.Run("throws error on permission denied", func(t *testing.T) { 57 // Setup in-memory fs 58 fsys := &fstest.OpenErrorFs{DenyPath: utils.ConfigPath} 59 // Run test 60 err := Run(fsys, nil, nil, utils.InitParams{}) 61 // Check error 62 assert.ErrorIs(t, err, os.ErrPermission) 63 }) 64 65 t.Run("throws error on failure to write config", func(t *testing.T) { 66 // Setup read-only fs 67 fsys := afero.NewReadOnlyFs(afero.NewMemMapFs()) 68 // Run test 69 assert.Error(t, Run(fsys, nil, nil, utils.InitParams{})) 70 }) 71 72 t.Run("throws error on seed failure", func(t *testing.T) { 73 // Setup in-memory fs 74 fsys := &fstest.OpenErrorFs{DenyPath: utils.SeedDataPath} 75 // Run test 76 err := Run(fsys, nil, nil, utils.InitParams{}) 77 // Check error 78 assert.ErrorIs(t, err, os.ErrPermission) 79 }) 80 81 t.Run("creates vscode settings file", func(t *testing.T) { 82 // Setup in-memory fs 83 fsys := &afero.MemMapFs{} 84 // Run test 85 assert.NoError(t, Run(fsys, utils.Ptr(true), nil, utils.InitParams{})) 86 // Validate generated vscode settings 87 exists, err := afero.Exists(fsys, settingsPath) 88 assert.NoError(t, err) 89 assert.True(t, exists) 90 exists, err = afero.Exists(fsys, extensionsPath) 91 assert.NoError(t, err) 92 assert.True(t, exists) 93 }) 94 95 t.Run("does not create vscode settings file", func(t *testing.T) { 96 // Setup in-memory fs 97 fsys := &afero.MemMapFs{} 98 // Run test 99 assert.NoError(t, Run(fsys, utils.Ptr(false), nil, utils.InitParams{})) 100 // Validate vscode settings file isn't generated 101 exists, err := afero.Exists(fsys, settingsPath) 102 assert.NoError(t, err) 103 assert.False(t, exists) 104 exists, err = afero.Exists(fsys, extensionsPath) 105 assert.NoError(t, err) 106 assert.False(t, exists) 107 }) 108 109 t.Run("creates intellij deno file", func(t *testing.T) { 110 // Setup in-memory fs 111 fsys := &afero.MemMapFs{} 112 // Run test 113 assert.NoError(t, Run(fsys, nil, utils.Ptr(true), utils.InitParams{})) 114 // Validate generated intellij deno config 115 exists, err := afero.Exists(fsys, denoPath) 116 assert.NoError(t, err) 117 assert.True(t, exists) 118 }) 119 120 t.Run("does not create intellij deno file", func(t *testing.T) { 121 // Setup in-memory fs 122 fsys := &afero.MemMapFs{} 123 // Run test 124 assert.NoError(t, Run(fsys, nil, utils.Ptr(false), utils.InitParams{})) 125 // Validate intellij deno config file isn't generated 126 exists, err := afero.Exists(fsys, denoPath) 127 assert.NoError(t, err) 128 assert.False(t, exists) 129 }) 130 } 131 132 func TestUpdateGitIgnore(t *testing.T) { 133 const ignorePath = "/home/supabase/.gitignore" 134 135 t.Run("appends to git ignore", func(t *testing.T) { 136 // Setup in-memory fs 137 fsys := &afero.MemMapFs{} 138 _, err := fsys.Create(ignorePath) 139 require.NoError(t, err) 140 // Run test 141 assert.NoError(t, updateGitIgnore(ignorePath, fsys)) 142 // Validate file contents 143 content, err := afero.ReadFile(fsys, ignorePath) 144 assert.NoError(t, err) 145 assert.Equal(t, append([]byte("\n"), initGitignore...), content) 146 }) 147 148 t.Run("noop if already ignored", func(t *testing.T) { 149 // Setup read-only fs 150 fsys := &afero.MemMapFs{} 151 require.NoError(t, afero.WriteFile(fsys, ignorePath, initGitignore, 0644)) 152 // Run test 153 assert.NoError(t, updateGitIgnore(ignorePath, fsys)) 154 // Validate file contents 155 content, err := afero.ReadFile(fsys, ignorePath) 156 assert.NoError(t, err) 157 assert.Equal(t, initGitignore, content) 158 }) 159 160 t.Run("throws error on failure to open", func(t *testing.T) { 161 // Setup read-only fs 162 fsys := &fstest.OpenErrorFs{DenyPath: ignorePath} 163 // Run test 164 err := updateGitIgnore(ignorePath, fsys) 165 // Check error 166 assert.Error(t, err, os.ErrPermission) 167 }) 168 169 t.Run("throws error on failure to create", func(t *testing.T) { 170 // Setup read-only fs 171 fsys := afero.NewReadOnlyFs(afero.NewMemMapFs()) 172 // Run test 173 err := updateGitIgnore(ignorePath, fsys) 174 // Check error 175 assert.ErrorContains(t, err, "operation not permitted") 176 }) 177 } 178 179 func TestWriteVSCodeConfig(t *testing.T) { 180 t.Run("throws error on permission denied", func(t *testing.T) { 181 // Setup in-memory fs 182 fsys := afero.NewMemMapFs() 183 // Run test 184 err := writeVscodeConfig(afero.NewReadOnlyFs(fsys)) 185 // Check error 186 assert.ErrorIs(t, err, os.ErrPermission) 187 }) 188 189 t.Run("throws error on extensions failure", func(t *testing.T) { 190 // Setup in-memory fs 191 fsys := &fstest.OpenErrorFs{DenyPath: extensionsPath} 192 // Run test 193 err := writeVscodeConfig(fsys) 194 // Check error 195 assert.ErrorIs(t, err, os.ErrPermission) 196 }) 197 198 t.Run("throws error on settings failure", func(t *testing.T) { 199 // Setup in-memory fs 200 fsys := &fstest.OpenErrorFs{DenyPath: settingsPath} 201 // Run test 202 err := writeVscodeConfig(fsys) 203 // Check error 204 assert.ErrorIs(t, err, os.ErrPermission) 205 }) 206 } 207 208 func TestUpdateJsonFile(t *testing.T) { 209 t.Run("overwrites empty settings with template", func(t *testing.T) { 210 // Setup in-memory fs 211 fsys := afero.NewMemMapFs() 212 require.NoError(t, afero.WriteFile(fsys, settingsPath, []byte{}, 0644)) 213 // Run test 214 err := updateJsonFile(settingsPath, "{}", fsys) 215 // Check error 216 assert.NoError(t, err) 217 contents, err := afero.ReadFile(fsys, settingsPath) 218 assert.NoError(t, err) 219 assert.Equal(t, []byte("{}"), contents) 220 }) 221 222 t.Run("merges template into user settings", func(t *testing.T) { 223 // Setup in-memory fs 224 fsys := afero.NewMemMapFs() 225 require.NoError(t, afero.WriteFile(fsys, settingsPath, []byte(`{"a": true, "b": 123}`), 0644)) 226 // Run test 227 err := updateJsonFile(settingsPath, `{"b": 456, "c": false}`, fsys) 228 // Check error 229 assert.NoError(t, err) 230 f, err := fsys.Open(settingsPath) 231 assert.NoError(t, err) 232 var settings VSCodeSettings 233 dec := json.NewDecoder(f) 234 assert.NoError(t, dec.Decode(&settings)) 235 assert.Equal(t, VSCodeSettings{ 236 "a": true, 237 "b": float64(456), 238 "c": false, 239 }, settings) 240 }) 241 242 t.Run("throws error on merge failure", func(t *testing.T) { 243 // Setup in-memory fs 244 fsys := afero.NewMemMapFs() 245 require.NoError(t, afero.WriteFile(fsys, settingsPath, []byte("{}"), 0644)) 246 // Run test 247 err := updateJsonFile(settingsPath, "", fsys) 248 // Check error 249 assert.ErrorContains(t, err, "failed to copy template:") 250 }) 251 252 t.Run("throws error on save failure", func(t *testing.T) { 253 // Setup in-memory fs 254 fsys := afero.NewMemMapFs() 255 require.NoError(t, afero.WriteFile(fsys, settingsPath, []byte("{}"), 0644)) 256 // Run test 257 err := updateJsonFile(settingsPath, "{}", afero.NewReadOnlyFs(fsys)) 258 // Check error 259 assert.ErrorContains(t, err, "operation not permitted") 260 }) 261 }