diff --git a/backend/internal/handlers/buckets_test.go b/backend/internal/handlers/buckets_test.go index 754a3f9..8f40988 100644 --- a/backend/internal/handlers/buckets_test.go +++ b/backend/internal/handlers/buckets_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "Noooste/garage-ui/internal/apierr" "Noooste/garage-ui/internal/models" "Noooste/garage-ui/internal/services/mocks" @@ -426,3 +427,37 @@ func TestUpdateBucketWebsite_Disable(t *testing.T) { t.Fatalf("status = %d", resp.StatusCode) } } + +func TestDeleteBucket_UpstreamBucketNotEmpty(t *testing.T) { + app, admin := newBucketsTestApp(t) + admin.GetBucketInfoByAliasFn = func(_ context.Context, _ string) (*models.GarageBucketInfo, error) { + return &models.GarageBucketInfo{ID: "id-1"}, nil + } + admin.DeleteBucketFn = func(_ context.Context, _ string) error { + return &apierr.UpstreamError{ + HTTPStatus: 409, + Code: "BucketNotEmpty", + Message: "Tried to delete a non-empty bucket", + Source: "garage", + } + } + resp, err := app.Test(httptest.NewRequest(http.MethodDelete, "/buckets/alpha", nil)) + if err != nil { + t.Fatalf("app.Test: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusConflict { + t.Fatalf("status = %d, want 409", resp.StatusCode) + } + var body models.APIResponse + decodeJSON(t, resp.Body, &body) + if body.Error == nil { + t.Fatal("error missing from response body") + } + if body.Error.Code != models.ErrCodeBucketNotEmpty { + t.Errorf("code = %q, want %s", body.Error.Code, models.ErrCodeBucketNotEmpty) + } + if body.Error.Message != "Tried to delete a non-empty bucket" { + t.Errorf("message = %q", body.Error.Message) + } +} diff --git a/backend/internal/handlers/objects_test.go b/backend/internal/handlers/objects_test.go index ee066c5..b6458ed 100644 --- a/backend/internal/handlers/objects_test.go +++ b/backend/internal/handlers/objects_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "Noooste/garage-ui/internal/apierr" "Noooste/garage-ui/internal/models" "Noooste/garage-ui/internal/services" "Noooste/garage-ui/internal/services/mocks" @@ -868,3 +869,32 @@ func TestCreateDirectory_ServiceError500(t *testing.T) { t.Fatalf("status = %d, want 500", resp.StatusCode) } } + +func TestDeleteObject_UpstreamNoSuchKey(t *testing.T) { + app, s3 := newObjectsTestApp(t) + s3.ObjectExistsFn = func(_ context.Context, _, _ string) (bool, error) { return true, nil } + s3.DeleteObjectFn = func(_ context.Context, _, _ string) error { + return &apierr.UpstreamError{ + HTTPStatus: 404, + Code: "NoSuchKey", + Message: "The specified key does not exist", + Source: "s3", + } + } + resp, err := app.Test(httptest.NewRequest(http.MethodDelete, "/buckets/b1/objects/foo.txt", nil)) + if err != nil { + t.Fatalf("app.Test: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusNotFound { + t.Fatalf("status = %d, want 404", resp.StatusCode) + } + var body models.APIResponse + decodeJSON(t, resp.Body, &body) + if body.Error == nil || body.Error.Code != models.ErrCodeObjectNotFound { + t.Fatalf("error = %+v, want code %s", body.Error, models.ErrCodeObjectNotFound) + } + if body.Error.Message != "The specified key does not exist" { + t.Errorf("message = %q", body.Error.Message) + } +} diff --git a/backend/internal/handlers/users_test.go b/backend/internal/handlers/users_test.go index 30c9065..bd38a21 100644 --- a/backend/internal/handlers/users_test.go +++ b/backend/internal/handlers/users_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "Noooste/garage-ui/internal/apierr" "Noooste/garage-ui/internal/models" "Noooste/garage-ui/internal/services/mocks" @@ -365,3 +366,31 @@ func TestUpdateUser_AdminError500(t *testing.T) { t.Fatalf("status = %d, want 500", resp.StatusCode) } } + +func TestDeleteUser_UpstreamAccessDenied(t *testing.T) { + app, admin := newUsersTestApp(t) + admin.DeleteKeyFn = func(_ context.Context, _ string) error { + return &apierr.UpstreamError{ + HTTPStatus: 403, + Code: "AccessDenied", + Message: "permission denied", + Source: "garage", + } + } + resp, err := app.Test(httptest.NewRequest(http.MethodDelete, "/users/abc", nil)) + if err != nil { + t.Fatalf("app.Test: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusForbidden { + t.Fatalf("status = %d, want 403", resp.StatusCode) + } + var body models.APIResponse + decodeJSON(t, resp.Body, &body) + if body.Error == nil || body.Error.Code != models.ErrCodeForbidden { + t.Fatalf("error = %+v, want code %s", body.Error, models.ErrCodeForbidden) + } + if body.Error.Message != "permission denied" { + t.Errorf("message = %q", body.Error.Message) + } +}