Repository: cloudflare/cloudflare-go
Pull request #1496 (2024-02-05 02:54:00)

AUTH-5608 added warp auth fields to access organizations and apps


## Description

<!--
Describe your changes in detail through motivation and context. Why is
this change required? What problem does it solve? If it fixes an open
issue, link to the issue using GitHub's closing issues keywords[1].
-->
## Has your change been tested?

Unit tests

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented in [cloudflare/api-schemas](https://github.com/cloudflare/api-schemas) 
      and relies on stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/



Patch:
diff --git a/.changelog/1492.txt b/.changelog/1492.txt
deleted file mode 100644
index f46c87416..000000000
--- a/.changelog/1492.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:enhancement
-hyperdrive: Add support for hyperdrive CRUD operations
-```
diff --git a/.changelog/1496.txt b/.changelog/1496.txt
new file mode 100644
index 000000000..5d3ea2857
--- /dev/null
+++ b/.changelog/1496.txt
@@ -0,0 +1,7 @@
+```release-note:enhancement
+access_application: Add support for `allow_authenticate_via_warp`
+```
+
+```release-note:enhancement
+access_organization: Add support for `allow_authenticate_via_warp` and `warp_auth_session_duration`
+```
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 932ae1fa2..2a2f071b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,5 @@
 ## 0.88.0 (Unreleased)
 
-ENHANCEMENTS:
-
-* hyperdrive: Add support for hyperdrive CRUD operations ([#1492](https://github.com/cloudflare/cloudflare-go/issues/1492))
-
 ## 0.87.0 (January 31st, 2024)
 
 ENHANCEMENTS:
diff --git a/access_application.go b/access_application.go
index 98b240ae7..f61065991 100644
--- a/access_application.go
+++ b/access_application.go
@@ -52,6 +52,7 @@ type AccessApplication struct {
 	HttpOnlyCookieAttribute  *bool                          `json:"http_only_cookie_attribute,omitempty"`
 	ServiceAuth401Redirect   *bool                          `json:"service_auth_401_redirect,omitempty"`
 	PathCookieAttribute      *bool                          `json:"path_cookie_attribute,omitempty"`
+	AllowAuthenticateViaWarp *bool                          `json:"allow_authenticate_via_warp,omitempty"`
 	CustomPages              []string                       `json:"custom_pages,omitempty"`
 	Tags                     []string                       `json:"tags,omitempty"`
 	AccessAppLauncherCustomization
@@ -166,6 +167,7 @@ type CreateAccessApplicationParams struct {
 	SessionDuration          string                         `json:"session_duration,omitempty"`
 	SkipInterstitial         *bool                          `json:"skip_interstitial,omitempty"`
 	Type                     AccessApplicationType          `json:"type,omitempty"`
+	AllowAuthenticateViaWarp *bool                          `json:"allow_authenticate_via_warp,omitempty"`
 	CustomPages              []string                       `json:"custom_pages,omitempty"`
 	Tags                     []string                       `json:"tags,omitempty"`
 	AccessAppLauncherCustomization
@@ -196,6 +198,7 @@ type UpdateAccessApplicationParams struct {
 	SessionDuration          string                         `json:"session_duration,omitempty"`
 	SkipInterstitial         *bool                          `json:"skip_interstitial,omitempty"`
 	Type                     AccessApplicationType          `json:"type,omitempty"`
+	AllowAuthenticateViaWarp *bool                          `json:"allow_authenticate_via_warp,omitempty"`
 	CustomPages              []string                       `json:"custom_pages,omitempty"`
 	Tags                     []string                       `json:"tags,omitempty"`
 	AccessAppLauncherCustomization
diff --git a/access_organization.go b/access_organization.go
index bb02b1ca4..f7eea16af 100644
--- a/access_organization.go
+++ b/access_organization.go
@@ -22,6 +22,8 @@ type AccessOrganization struct {
 	AutoRedirectToIdentity         *bool                         `json:"auto_redirect_to_identity,omitempty"`
 	SessionDuration                *string                       `json:"session_duration,omitempty"`
 	CustomPages                    AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
+	WarpAuthSessionDuration        *string                       `json:"warp_auth_session_duration,omitempty"`
+	AllowAuthenticateViaWarp       *bool                         `json:"allow_authenticate_via_warp,omitempty"`
 }
 
 // AccessOrganizationLoginDesign represents the login design options.
@@ -67,6 +69,8 @@ type CreateAccessOrganizationParams struct {
 	AutoRedirectToIdentity         *bool                         `json:"auto_redirect_to_identity,omitempty"`
 	SessionDuration                *string                       `json:"session_duration,omitempty"`
 	CustomPages                    AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
+	WarpAuthSessionDuration        *string                       `json:"warp_auth_session_duration,omitempty"`
+	AllowAuthenticateViaWarp       *bool                         `json:"allow_authenticate_via_warp,omitempty"`
 }
 
 type UpdateAccessOrganizationParams struct {
@@ -79,6 +83,8 @@ type UpdateAccessOrganizationParams struct {
 	AutoRedirectToIdentity         *bool                         `json:"auto_redirect_to_identity,omitempty"`
 	SessionDuration                *string                       `json:"session_duration,omitempty"`
 	CustomPages                    AccessOrganizationCustomPages `json:"custom_pages,omitempty"`
+	WarpAuthSessionDuration        *string                       `json:"warp_auth_session_duration,omitempty"`
+	AllowAuthenticateViaWarp       *bool                         `json:"allow_authenticate_via_warp,omitempty"`
 }
 
 func (api *API) GetAccessOrganization(ctx context.Context, rc *ResourceContainer, params GetAccessOrganizationParams) (AccessOrganization, ResultInfo, error) {
diff --git a/hyperdrive.go b/hyperdrive.go
deleted file mode 100644
index 346eb1ccb..000000000
--- a/hyperdrive.go
+++ /dev/null
@@ -1,195 +0,0 @@
-package cloudflare
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"net/http"
-
-	"github.com/goccy/go-json"
-)
-
-var (
-	ErrMissingHyperdriveConfigID       = errors.New("required hyperdrive config id is missing")
-	ErrMissingHyperdriveConfigName     = errors.New("required hyperdrive config name is missing")
-	ErrMissingHyperdriveConfigPassword = errors.New("required hyperdrive config password is missing")
-)
-
-type HyperdriveConfig struct {
-	ID      string                  `json:"id,omitempty"`
-	Name    string                  `json:"name,omitempty"`
-	Origin  HyperdriveConfigOrigin  `json:"origin,omitempty"`
-	Caching HyperdriveConfigCaching `json:"caching,omitempty"`
-}
-
-type HyperdriveConfigOrigin struct {
-	Database string `json:"database,omitempty"`
-	Host     string `json:"host,omitempty"`
-	Port     int    `json:"port,omitempty"`
-	Scheme   string `json:"scheme,omitempty"`
-	User     string `json:"user,omitempty"`
-}
-
-type HyperdriveConfigCaching struct {
-	Disabled             *bool `json:"disabled,omitempty"`
-	MaxAge               int   `json:"max_age,omitempty"`
-	StaleWhileRevalidate int   `json:"stale_while_revalidate,omitempty"`
-}
-
-type HyperdriveConfigListResponse struct {
-	Response
-	Result []HyperdriveConfig `json:"result"`
-}
-
-type CreateHyperdriveConfigParams struct {
-	Name     string                  `json:"name"`
-	Password string                  `json:"password"`
-	Origin   HyperdriveConfigOrigin  `json:"origin"`
-	Caching  HyperdriveConfigCaching `json:"caching,omitempty"`
-}
-
-type HyperdriveConfigResponse struct {
-	Response
-	Result HyperdriveConfig `json:"result"`
-}
-
-type UpdateHyperdriveConfigParams struct {
-	HyperdriveID string                  `json:"-"`
-	Name         string                  `json:"name"`
-	Password     string                  `json:"password"`
-	Origin       HyperdriveConfigOrigin  `json:"origin"`
-	Caching      HyperdriveConfigCaching `json:"caching,omitempty"`
-}
-
-type ListHyperdriveConfigParams struct{}
-
-// ListHyperdriveConfigs returns the Hyperdrive configs owned by an account.
-//
-// API reference: https://developers.cloudflare.com/api/operations/list-hyperdrive
-func (api *API) ListHyperdriveConfigs(ctx context.Context, rc *ResourceContainer, params ListHyperdriveConfigParams) ([]HyperdriveConfig, error) {
-	if rc.Identifier == "" {
-		return []HyperdriveConfig{}, ErrMissingAccountID
-	}
-
-	hResponse := HyperdriveConfigListResponse{}
-	uri := fmt.Sprintf("/accounts/%s/hyperdrive/configs", rc.Identifier)
-
-	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
-	if err != nil {
-		return []HyperdriveConfig{}, err
-	}
-
-	err = json.Unmarshal(res, &hResponse)
-	if err != nil {
-		return []HyperdriveConfig{}, fmt.Errorf("failed to unmarshal filters JSON data: %w", err)
-	}
-
-	return hResponse.Result, nil
-}
-
-// CreateHyperdriveConfig creates a new Hyperdrive config.
-//
-// API reference: https://developers.cloudflare.com/api/operations/create-hyperdrive
-func (api *API) CreateHyperdriveConfig(ctx context.Context, rc *ResourceContainer, params CreateHyperdriveConfigParams) (HyperdriveConfig, error) {
-	if rc.Identifier == "" {
-		return HyperdriveConfig{}, ErrMissingAccountID
-	}
-
-	if params.Name == "" {
-		return HyperdriveConfig{}, ErrMissingHyperdriveConfigName
-	}
-
-	if params.Password == "" {
-		return HyperdriveConfig{}, ErrMissingHyperdriveConfigPassword
-	}
-
-	uri := fmt.Sprintf("/accounts/%s/hyperdrive/configs", rc.Identifier)
-
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
-	if err != nil {
-		return HyperdriveConfig{}, err
-	}
-
-	var r HyperdriveConfigResponse
-	err = json.Unmarshal(res, &r)
-	if err != nil {
-		return HyperdriveConfig{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
-	}
-
-	return r.Result, nil
-}
-
-// DeleteHyperdriveConfig deletes a Hyperdrive config.
-//
-// API reference: https://developers.cloudflare.com/api/operations/delete-hyperdrive
-func (api *API) DeleteHyperdriveConfig(ctx context.Context, rc *ResourceContainer, hyperdriveID string) error {
-	if rc.Identifier == "" {
-		return ErrMissingAccountID
-	}
-	if hyperdriveID == "" {
-		return ErrMissingHyperdriveConfigID
-	}
-
-	uri := fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", rc.Identifier, hyperdriveID)
-	_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
-	if err != nil {
-		return fmt.Errorf("%s: %w", errMakeRequestError, err)
-	}
-
-	return nil
-}
-
-// GetHyperdriveConfig returns a single Hyperdrive config based on the ID.
-//
-// API reference: https://developers.cloudflare.com/api/operations/get-hyperdrive
-func (api *API) GetHyperdriveConfig(ctx context.Context, rc *ResourceContainer, hyperdriveID string) (HyperdriveConfig, error) {
-	if rc.Identifier == "" {
-		return HyperdriveConfig{}, ErrMissingAccountID
-	}
-
-	if hyperdriveID == "" {
-		return HyperdriveConfig{}, ErrMissingHyperdriveConfigID
-	}
-
-	uri := fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", rc.Identifier, hyperdriveID)
-	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
-	if err != nil {
-		return HyperdriveConfig{}, err
-	}
-
-	var r HyperdriveConfigResponse
-	err = json.Unmarshal(res, &r)
-	if err != nil {
-		return HyperdriveConfig{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
-	}
-
-	return r.Result, nil
-}
-
-// UpdateHyperdriveConfig updates a Hyperdrive config.
-//
-// API reference: https://developers.cloudflare.com/api/operations/update-hyperdrive
-func (api *API) UpdateHyperdriveConfig(ctx context.Context, rc *ResourceContainer, params UpdateHyperdriveConfigParams) (HyperdriveConfig, error) {
-	if rc.Identifier == "" {
-		return HyperdriveConfig{}, ErrMissingAccountID
-	}
-
-	if params.HyperdriveID == "" {
-		return HyperdriveConfig{}, ErrMissingHyperdriveConfigID
-	}
-
-	uri := fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", rc.Identifier, params.HyperdriveID)
-
-	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
-	if err != nil {
-		return HyperdriveConfig{}, err
-	}
-
-	var r HyperdriveConfigResponse
-	err = json.Unmarshal(res, &r)
-	if err != nil {
-		return HyperdriveConfig{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
-	}
-
-	return r.Result, nil
-}


Test patch:
diff --git a/access_application_test.go b/access_application_test.go
index ed0916e03..4bf414b2b 100644
--- a/access_application_test.go
+++ b/access_application_test.go
@@ -49,7 +49,8 @@ func TestAccessApplications(t *testing.T) {
 					"service_auth_401_redirect": true,
 					"path_cookie_attribute": true,
 					"custom_pages": ["480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"],
-					"tags": ["engineers"]
+					"tags": ["engineers"],
+					"allow_authenticate_via_warp": true
 				}
 			],
 			"result_info": {
@@ -89,6 +90,7 @@ func TestAccessApplications(t *testing.T) {
 		CustomPages:              []string{"480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"},
 		Tags:                     []string{"engineers"},
 		CustomNonIdentityDenyURL: "https://blocked.com",
+		AllowAuthenticateViaWarp: BoolPtr(true),
 	}}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)
@@ -140,7 +142,8 @@ func TestAccessApplication(t *testing.T) {
 				"app_launcher_visible": true,
 				"service_auth_401_redirect": true,
 				"http_only_cookie_attribute": false,
-				"path_cookie_attribute": false
+				"path_cookie_attribute": false,
+				"allow_authenticate_via_warp": false
 			}
 		}
 		`)
@@ -171,6 +174,7 @@ func TestAccessApplication(t *testing.T) {
 		HttpOnlyCookieAttribute:  BoolPtr(false),
 		PathCookieAttribute:      BoolPtr(false),
 		CustomNonIdentityDenyURL: "https://blocked.com",
+		AllowAuthenticateViaWarp: BoolPtr(false),
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
@@ -221,7 +225,8 @@ func TestCreateAccessApplications(t *testing.T) {
 				"skip_interstitial": true,
 				"app_launcher_visible": true,
 				"service_auth_401_redirect": true,
-				"tags": ["engineers"]
+				"tags": ["engineers"],
+				"allow_authenticate_via_warp": false
 			}
 		}
 		`)
@@ -250,6 +255,7 @@ func TestCreateAccessApplications(t *testing.T) {
 		UpdatedAt:                &updatedAt,
 		CustomNonIdentityDenyURL: "https://blocked.com",
 		Tags:                     []string{"engineers"},
+		AllowAuthenticateViaWarp: BoolPtr(false),
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)
@@ -308,7 +314,8 @@ func TestUpdateAccessApplication(t *testing.T) {
 				"skip_interstitial": true,
 				"app_launcher_visible": true,
 				"service_auth_401_redirect": true,
-				"tags": ["engineers"]
+				"tags": ["engineers"],
+				"allow_authenticate_via_warp": true
 			}
 		}
 		`)
@@ -333,6 +340,7 @@ func TestUpdateAccessApplication(t *testing.T) {
 		CustomNonIdentityDenyURL: "https://blocked.com",
 		Tags:                     []string{"engineers"},
 		SkipInterstitial:         BoolPtr(true),
+		AllowAuthenticateViaWarp: BoolPtr(true),
 		CreatedAt:                &createdAt,
 		UpdatedAt:                &updatedAt,
 	}
@@ -356,6 +364,7 @@ func TestUpdateAccessApplication(t *testing.T) {
 		SkipInterstitial:         BoolPtr(true),
 		CustomNonIdentityDenyURL: "https://blocked.com",
 		Tags:                     []string{"engineers"},
+		AllowAuthenticateViaWarp: BoolPtr(true),
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
diff --git a/access_organization_test.go b/access_organization_test.go
index 295a7f7d8..fc9cfb4bf 100644
--- a/access_organization_test.go
+++ b/access_organization_test.go
@@ -29,6 +29,8 @@ func TestAccessOrganization(t *testing.T) {
 				"is_ui_read_only": false,
 				"user_seat_expiration_inactive_time": "720h",
 				"auto_redirect_to_identity": true,
+				"allow_authenticate_via_warp": true,
+				"warp_auth_session_duration": "24h",
 				"session_duration": "12h",
 				"login_design": {
 					"background_color": "#c5ed1b",
@@ -46,10 +48,12 @@ func TestAccessOrganization(t *testing.T) {
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 
 	want := AccessOrganization{
-		Name:       "Widget Corps Internal Applications",
-		CreatedAt:  &createdAt,
-		UpdatedAt:  &updatedAt,
-		AuthDomain: "test.cloudflareaccess.com",
+		Name:                     "Widget Corps Internal Applications",
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		AuthDomain:               "test.cloudflareaccess.com",
+		AllowAuthenticateViaWarp: BoolPtr(true),
+		WarpAuthSessionDuration:  StringPtr("24h"),
 		LoginDesign: AccessOrganizationLoginDesign{
 			BackgroundColor: "#c5ed1b",
 			LogoPath:        "https://example.com/logo.png",
@@ -96,6 +100,8 @@ func TestCreateAccessOrganization(t *testing.T) {
 				"updated_at": "2014-01-01T05:20:00.12345Z",
 				"name": "Widget Corps Internal Applications",
 				"auth_domain": "test.cloudflareaccess.com",
+				"allow_authenticate_via_warp": true,
+				"warp_auth_session_duration": "24h",
 				"is_ui_read_only": true,
 				"session_duration": "12h",
 				"login_design": {
@@ -114,10 +120,12 @@ func TestCreateAccessOrganization(t *testing.T) {
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 
 	want := AccessOrganization{
-		CreatedAt:  &createdAt,
-		UpdatedAt:  &updatedAt,
-		Name:       "Widget Corps Internal Applications",
-		AuthDomain: "test.cloudflareaccess.com",
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		Name:                     "Widget Corps Internal Applications",
+		AuthDomain:               "test.cloudflareaccess.com",
+		AllowAuthenticateViaWarp: BoolPtr(true),
+		WarpAuthSessionDuration:  StringPtr("24h"),
 		LoginDesign: AccessOrganizationLoginDesign{
 			BackgroundColor: "#c5ed1b",
 			LogoPath:        "https://example.com/logo.png",
@@ -186,6 +194,8 @@ func TestUpdateAccessOrganization(t *testing.T) {
 				"updated_at": "2014-01-01T05:20:00.12345Z",
 				"name": "Widget Corps Internal Applications",
 				"auth_domain": "test.cloudflareaccess.com",
+				"allow_authenticate_via_warp": false,
+				"warp_auth_session_duration": "18h",
 				"login_design": {
 					"background_color": "#c5ed1b",
 					"logo_path": "https://example.com/logo.png",
@@ -205,10 +215,12 @@ func TestUpdateAccessOrganization(t *testing.T) {
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 
 	want := AccessOrganization{
-		CreatedAt:  &createdAt,
-		UpdatedAt:  &updatedAt,
-		Name:       "Widget Corps Internal Applications",
-		AuthDomain: "test.cloudflareaccess.com",
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		Name:                     "Widget Corps Internal Applications",
+		AuthDomain:               "test.cloudflareaccess.com",
+		WarpAuthSessionDuration:  StringPtr("18h"),
+		AllowAuthenticateViaWarp: BoolPtr(false),
 		LoginDesign: AccessOrganizationLoginDesign{
 			BackgroundColor: "#c5ed1b",
 			LogoPath:        "https://example.com/logo.png",
@@ -233,9 +245,11 @@ func TestUpdateAccessOrganization(t *testing.T) {
 			HeaderText:      "Widget Corp",
 			FooterText:      "© Widget Corp",
 		},
-		IsUIReadOnly:           BoolPtr(false),
-		SessionDuration:        StringPtr("12h"),
-		UIReadOnlyToggleReason: "this is my reason",
+		WarpAuthSessionDuration:  StringPtr("18h"),
+		AllowAuthenticateViaWarp: BoolPtr(false),
+		IsUIReadOnly:             BoolPtr(false),
+		SessionDuration:          StringPtr("12h"),
+		UIReadOnlyToggleReason:   "this is my reason",
 	})
 
 	if assert.NoError(t, err) {
@@ -254,9 +268,11 @@ func TestUpdateAccessOrganization(t *testing.T) {
 			HeaderText:      "Widget Corp",
 			FooterText:      "© Widget Corp",
 		},
-		IsUIReadOnly:           BoolPtr(false),
-		UIReadOnlyToggleReason: "this is my reason",
-		SessionDuration:        StringPtr("12h"),
+		WarpAuthSessionDuration:  StringPtr("18h"),
+		AllowAuthenticateViaWarp: BoolPtr(false),
+		IsUIReadOnly:             BoolPtr(false),
+		UIReadOnlyToggleReason:   "this is my reason",
+		SessionDuration:          StringPtr("12h"),
 	})
 
 	if assert.NoError(t, err) {
diff --git a/hyperdrive_test.go b/hyperdrive_test.go
deleted file mode 100644
index 633ce9cbb..000000000
--- a/hyperdrive_test.go
+++ /dev/null
@@ -1,285 +0,0 @@
-package cloudflare
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-const (
-	testHyperdriveConfigId   = "6b7efc370ea34ded8327fa20698dfe3a"
-	testHyperdriveConfigName = "example-hyperdrive"
-)
-
-func testHyperdriveConfig() HyperdriveConfig {
-	return HyperdriveConfig{
-		ID:   testHyperdriveConfigId,
-		Name: testHyperdriveConfigName,
-		Origin: HyperdriveConfigOrigin{
-			Database: "postgres",
-			Host:     "database.example.com",
-			Port:     5432,
-			Scheme:   "postgres",
-			User:     "postgres",
-		},
-		Caching: HyperdriveConfigCaching{
-			Disabled:             BoolPtr(false),
-			MaxAge:               30,
-			StaleWhileRevalidate: 15,
-		},
-	}
-}
-
-func TestHyperdriveConfig_List(t *testing.T) {
-	setup()
-	defer teardown()
-
-	mux.HandleFunc(fmt.Sprintf("/accounts/%s/hyperdrive/configs", testAccountID), func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": [{
-				"id": "6b7efc370ea34ded8327fa20698dfe3a",
-				"caching": {
-					"disabled": false,
-					"max_age": 30,
-					"stale_while_revalidate": 15
-				},
-				"name": "example-hyperdrive",
-				"origin": {
-					"database": "postgres",
-					"host": "database.example.com",
-					"port": 5432,
-					"scheme": "postgres",
-					"user": "postgres"
-				}
-			}]
-		}`)
-	})
-
-	_, err := client.ListHyperdriveConfigs(context.Background(), AccountIdentifier(""), ListHyperdriveConfigParams{})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingAccountID, err)
-	}
-
-	result, err := client.ListHyperdriveConfigs(context.Background(), AccountIdentifier(testAccountID), ListHyperdriveConfigParams{})
-	if assert.NoError(t, err) {
-		assert.Equal(t, 1, len(result))
-		assert.Equal(t, testHyperdriveConfig(), result[0])
-	}
-}
-
-func TestHyperdriveConfig_Get(t *testing.T) {
-	setup()
-	defer teardown()
-
-	mux.HandleFunc(fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", testAccountID, testHyperdriveConfigId), func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": {
-				"id": "6b7efc370ea34ded8327fa20698dfe3a",
-				"caching": {
-					"disabled": false,
-					"max_age": 30,
-					"stale_while_revalidate": 15
-				},
-				"name": "example-hyperdrive",
-				"origin": {
-					"database": "postgres",
-					"host": "database.example.com",
-					"port": 5432,
-					"scheme": "postgres",
-					"user": "postgres"
-				}
-			}
-		}`)
-	})
-
-	_, err := client.GetHyperdriveConfig(context.Background(), AccountIdentifier(""), "")
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingAccountID, err)
-	}
-
-	_, err = client.GetHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), "")
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingHyperdriveConfigID, err)
-	}
-
-	result, err := client.GetHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), testHyperdriveConfigId)
-	if assert.NoError(t, err) {
-		assert.Equal(t, testHyperdriveConfig(), result)
-	}
-}
-
-func TestHyperdriveConfig_Create(t *testing.T) {
-	setup()
-	defer teardown()
-
-	mux.HandleFunc(fmt.Sprintf("/accounts/%s/hyperdrive/configs", testAccountID), func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": {
-				"id": "6b7efc370ea34ded8327fa20698dfe3a",
-				"caching": {
-					"disabled": false,
-					"max_age": 30,
-					"stale_while_revalidate": 15
-				},
-				"name": "example-hyperdrive",
-				"origin": {
-					"database": "postgres",
-					"host": "database.example.com",
-					"port": 5432,
-					"scheme": "postgres",
-					"user": "postgres"
-				}
-			}
-		}`)
-	})
-
-	_, err := client.CreateHyperdriveConfig(context.Background(), AccountIdentifier(""), CreateHyperdriveConfigParams{})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingAccountID, err)
-	}
-
-	_, err = client.CreateHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), CreateHyperdriveConfigParams{})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingHyperdriveConfigName, err)
-	}
-
-	_, err = client.CreateHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), CreateHyperdriveConfigParams{Name: "example-hyperdrive"})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingHyperdriveConfigPassword, err)
-	}
-
-	result, err := client.CreateHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), CreateHyperdriveConfigParams{
-		Name:     "example-hyperdrive",
-		Password: "password",
-		Origin: HyperdriveConfigOrigin{
-			Database: "postgres",
-			Host:     "database.example.com",
-			Port:     5432,
-			Scheme:   "postgres",
-			User:     "postgres",
-		},
-		Caching: HyperdriveConfigCaching{
-			Disabled:             BoolPtr(false),
-			MaxAge:               30,
-			StaleWhileRevalidate: 15,
-		},
-	})
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, testHyperdriveConfig(), result)
-	}
-}
-
-func TestHyperdriveConfig_Delete(t *testing.T) {
-	setup()
-	defer teardown()
-
-	mux.HandleFunc(fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", testAccountID, testHyperdriveConfigId), func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": null
-		}`)
-	})
-	err := client.DeleteHyperdriveConfig(context.Background(), AccountIdentifier(""), "")
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingAccountID, err)
-	}
-
-	err = client.DeleteHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), "")
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingHyperdriveConfigID, err)
-	}
-
-	err = client.DeleteHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), testHyperdriveConfigId)
-	assert.NoError(t, err)
-}
-
-func TestHyperdriveConfig_Update(t *testing.T) {
-	setup()
-	defer teardown()
-
-	mux.HandleFunc(fmt.Sprintf("/accounts/%s/hyperdrive/configs/%s", testAccountID, testHyperdriveConfigId), func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": {
-				"id": "6b7efc370ea34ded8327fa20698dfe3a",
-				"caching": {
-					"disabled": false,
-					"max_age": 30,
-					"stale_while_revalidate": 15
-				},
-				"name": "example-hyperdrive",
-				"origin": {
-					"database": "postgres",
-					"host": "database.example.com",
-					"port": 5432,
-					"scheme": "postgres",
-					"user": "postgres"
-				}
-			}
-		}`)
-	})
-
-	_, err := client.UpdateHyperdriveConfig(context.Background(), AccountIdentifier(""), UpdateHyperdriveConfigParams{})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingAccountID, err)
-	}
-
-	_, err = client.UpdateHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), UpdateHyperdriveConfigParams{})
-	if assert.Error(t, err) {
-		assert.Equal(t, ErrMissingHyperdriveConfigID, err)
-	}
-
-	result, err := client.UpdateHyperdriveConfig(context.Background(), AccountIdentifier(testAccountID), UpdateHyperdriveConfigParams{
-		HyperdriveID: "6b7efc370ea34ded8327fa20698dfe3a",
-		Name:         "example-hyperdrive",
-		Password:     "password",
-		Origin: HyperdriveConfigOrigin{
-			Database: "postgres",
-			Host:     "database.example.com",
-			Port:     5432,
-			Scheme:   "postgres",
-			User:     "postgres",
-		},
-		Caching: HyperdriveConfigCaching{
-			Disabled:             BoolPtr(false),
-			MaxAge:               30,
-			StaleWhileRevalidate: 15,
-		},
-	})
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, testHyperdriveConfig(), result)
-	}
-}