github.com/Redstoneguy129/cli@v0.0.0-20230211220159-15dca4e91917/internal/functions/delete/delete_test.go (about)

     1  package delete
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"testing"
     8  
     9  	"github.com/spf13/afero"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/Redstoneguy129/cli/internal/testing/apitest"
    13  	"github.com/Redstoneguy129/cli/internal/utils"
    14  	"github.com/Redstoneguy129/cli/pkg/api"
    15  	"gopkg.in/h2non/gock.v1"
    16  )
    17  
    18  func TestDeleteCommand(t *testing.T) {
    19  	t.Run("deletes function from project", func(t *testing.T) {
    20  		// Setup in-memory fs
    21  		fsys := afero.NewMemMapFs()
    22  		// Setup valid project ref
    23  		project := apitest.RandomProjectRef()
    24  		require.NoError(t, afero.WriteFile(fsys, utils.ProjectRefPath, []byte(project), 0644))
    25  		// Setup valid access token
    26  		token := apitest.RandomAccessToken(t)
    27  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
    28  		// Setup mock api
    29  		defer gock.OffAll()
    30  		gock.New("https://api.supabase.io").
    31  			Get("/v1/projects/" + project + "/functions/test-func").
    32  			Reply(http.StatusOK).
    33  			JSON(api.FunctionResponse{Id: "1"})
    34  		gock.New("https://api.supabase.io").
    35  			Delete("/v1/projects/" + project + "/functions/test-func").
    36  			Reply(http.StatusOK)
    37  		// Run test
    38  		assert.NoError(t, Run(context.Background(), "test-func", "", fsys))
    39  		// Validate api
    40  		assert.Empty(t, apitest.ListUnmatchedRequests())
    41  	})
    42  
    43  	t.Run("throws error on malformed ref", func(t *testing.T) {
    44  		// Setup in-memory fs
    45  		fsys := afero.NewMemMapFs()
    46  		// Setup invalid project ref
    47  		require.NoError(t, afero.WriteFile(fsys, utils.ProjectRefPath, []byte("test-project"), 0644))
    48  		// Run test
    49  		err := Run(context.Background(), "test-func", "", fsys)
    50  		// Check error
    51  		assert.ErrorContains(t, err, "Invalid project ref format.")
    52  	})
    53  
    54  	t.Run("throws error on malformed ref arg", func(t *testing.T) {
    55  		// Setup in-memory fs
    56  		fsys := afero.NewMemMapFs()
    57  		// Run test
    58  		err := Run(context.Background(), "test-func", "test-project", fsys)
    59  		// Check error
    60  		assert.ErrorContains(t, err, "Invalid project ref format.")
    61  	})
    62  
    63  	t.Run("throws error on malformed slug", func(t *testing.T) {
    64  		// Setup in-memory fs
    65  		fsys := afero.NewMemMapFs()
    66  		// Setup valid project ref
    67  		project := apitest.RandomProjectRef()
    68  		// Run test
    69  		err := Run(context.Background(), "@", project, fsys)
    70  		// Check error
    71  		assert.ErrorContains(t, err, "Invalid Function name.")
    72  	})
    73  
    74  	t.Run("throws error on network failure", func(t *testing.T) {
    75  		// Setup in-memory fs
    76  		fsys := afero.NewMemMapFs()
    77  		// Setup valid project ref
    78  		project := apitest.RandomProjectRef()
    79  		// Setup valid access token
    80  		token := apitest.RandomAccessToken(t)
    81  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
    82  		// Setup mock api
    83  		defer gock.OffAll()
    84  		gock.New("https://api.supabase.io").
    85  			Get("/v1/projects/" + project + "/functions/test-func").
    86  			ReplyError(errors.New("network error"))
    87  		// Run test
    88  		err := Run(context.Background(), "test-func", project, fsys)
    89  		// Check error
    90  		assert.ErrorContains(t, err, "network error")
    91  		assert.Empty(t, apitest.ListUnmatchedRequests())
    92  	})
    93  
    94  	t.Run("throws error on service unavailable", func(t *testing.T) {
    95  		// Setup in-memory fs
    96  		fsys := afero.NewMemMapFs()
    97  		// Setup valid project ref
    98  		project := apitest.RandomProjectRef()
    99  		// Setup valid access token
   100  		token := apitest.RandomAccessToken(t)
   101  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
   102  		// Setup mock api
   103  		defer gock.OffAll()
   104  		gock.New("https://api.supabase.io").
   105  			Get("/v1/projects/" + project + "/functions/test-func").
   106  			Reply(http.StatusServiceUnavailable)
   107  		// Run test
   108  		err := Run(context.Background(), "test-func", project, fsys)
   109  		// Check error
   110  		assert.ErrorContains(t, err, "Unexpected error deleting Function:")
   111  		assert.Empty(t, apitest.ListUnmatchedRequests())
   112  	})
   113  
   114  	t.Run("throws error on missing function", func(t *testing.T) {
   115  		// Setup in-memory fs
   116  		fsys := afero.NewMemMapFs()
   117  		// Setup valid project ref
   118  		project := apitest.RandomProjectRef()
   119  		// Setup valid access token
   120  		token := apitest.RandomAccessToken(t)
   121  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
   122  		// Setup mock api
   123  		defer gock.OffAll()
   124  		gock.New("https://api.supabase.io").
   125  			Get("/v1/projects/" + project + "/functions/test-func").
   126  			Reply(http.StatusNotFound)
   127  		// Run test
   128  		err := Run(context.Background(), "test-func", project, fsys)
   129  		// Check error
   130  		assert.ErrorContains(t, err, "Function test-func does not exist on the Supabase project.")
   131  		assert.Empty(t, apitest.ListUnmatchedRequests())
   132  	})
   133  
   134  	t.Run("throws error on delete failure", func(t *testing.T) {
   135  		// Setup in-memory fs
   136  		fsys := afero.NewMemMapFs()
   137  		// Setup valid project ref
   138  		project := apitest.RandomProjectRef()
   139  		// Setup valid access token
   140  		token := apitest.RandomAccessToken(t)
   141  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
   142  		// Setup mock api
   143  		defer gock.OffAll()
   144  		gock.New("https://api.supabase.io").
   145  			Get("/v1/projects/" + project + "/functions/test-func").
   146  			Reply(http.StatusOK).
   147  			JSON(api.FunctionResponse{Id: "1"})
   148  		gock.New("https://api.supabase.io").
   149  			Delete("/v1/projects/" + project + "/functions/test-func").
   150  			Reply(http.StatusServiceUnavailable)
   151  		// Run test
   152  		err := Run(context.Background(), "test-func", project, fsys)
   153  		// Check error
   154  		assert.ErrorContains(t, err, "Failed to delete Function test-func on the Supabase project:")
   155  		assert.Empty(t, apitest.ListUnmatchedRequests())
   156  	})
   157  
   158  	t.Run("throws error on delete network failure", func(t *testing.T) {
   159  		// Setup in-memory fs
   160  		fsys := afero.NewMemMapFs()
   161  		// Setup valid project ref
   162  		project := apitest.RandomProjectRef()
   163  		// Setup valid access token
   164  		token := apitest.RandomAccessToken(t)
   165  		t.Setenv("SUPABASE_ACCESS_TOKEN", string(token))
   166  		// Setup mock api
   167  		defer gock.OffAll()
   168  		gock.New("https://api.supabase.io").
   169  			Get("/v1/projects/" + project + "/functions/test-func").
   170  			Reply(http.StatusOK).
   171  			JSON(api.FunctionResponse{Id: "1"})
   172  		gock.New("https://api.supabase.io").
   173  			Delete("/v1/projects/" + project + "/functions/test-func").
   174  			ReplyError(errors.New("network error"))
   175  		// Run test
   176  		err := Run(context.Background(), "test-func", project, fsys)
   177  		// Check error
   178  		assert.ErrorContains(t, err, "network error")
   179  		assert.Empty(t, apitest.ListUnmatchedRequests())
   180  	})
   181  }