Repository: cloudflare/cloudflare-go
Pull request #1340 (2023-07-19 20:52:21)

GATE-4074: Adds support for the new Protocol Detection feature to teams accounts
## Description

Adds support for the new ZT Account Protocol detection toggle

## Has your change been tested?

Updated tests


## 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.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] 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/1302.txt b/.changelog/1302.txt
deleted file mode 100644
index 9be4caa82..000000000
--- a/.changelog/1302.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:enhancement
-load_balancing: support header session affinity policy
-```
\ No newline at end of file
diff --git a/.changelog/1335.txt b/.changelog/1335.txt
deleted file mode 100644
index 13b520854..000000000
--- a/.changelog/1335.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:enhancement
-images: adds ability to upload image by url
-```
diff --git a/.changelog/1336.txt b/.changelog/1336.txt
deleted file mode 100644
index f949bdc25..000000000
--- a/.changelog/1336.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:enhancement
-zone: Added `GetRegionalTieredCache` and `UpdateRegionalTieredCache` to allow setting Regional Tiered Cache for a zone.
-```
diff --git a/.changelog/1339.txt b/.changelog/1339.txt
deleted file mode 100644
index 7326b4ede..000000000
--- a/.changelog/1339.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-```release-note:enhancement
-device_posture_rule: support certificate_id and cn for client_certificate posture rule
-```
-
-```release-note:enhancement
-device_posture_rule: support active_threats, network_status, infected, and is_active for sentinelone_s2s posture rule
-```
diff --git a/.changelog/1340.txt b/.changelog/1340.txt
new file mode 100644
index 000000000..beb399780
--- /dev/null
+++ b/.changelog/1340.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+teams-accounts: Adds support for protocol detection
+```
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a59ce1d0..238d67ab2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,4 @@
-## 0.74.0 (Unreleased)
-
-## 0.73.0 (July 19th, 2023)
+## 0.73.0 (Unreleased)
 
 BREAKING CHANGES:
 
@@ -21,14 +19,6 @@ BREAKING CHANGES:
 * rulesets: `UpdateZoneRulesetPhase` is removed in favour of `UpdateEntrypointRuleset` ([#1333](https://github.com/cloudflare/cloudflare-go/issues/1333))
 * rulesets: `UpdateZoneRuleset` is removed in favour of `UpdateRuleset` ([#1333](https://github.com/cloudflare/cloudflare-go/issues/1333))
 
-ENHANCEMENTS:
-
-* device_posture_rule: support active_threats, network_status, infected, and is_active for sentinelone_s2s posture rule ([#1339](https://github.com/cloudflare/cloudflare-go/issues/1339))
-* device_posture_rule: support certificate_id and cn for client_certificate posture rule ([#1339](https://github.com/cloudflare/cloudflare-go/issues/1339))
-* images: adds ability to upload image by url ([#1335](https://github.com/cloudflare/cloudflare-go/issues/1335))
-* load_balancing: support header session affinity policy ([#1302](https://github.com/cloudflare/cloudflare-go/issues/1302))
-* zone: Added `GetRegionalTieredCache` and `UpdateRegionalTieredCache` to allow setting Regional Tiered Cache for a zone. ([#1336](https://github.com/cloudflare/cloudflare-go/issues/1336))
-
 DEPENDENCIES:
 
 * deps: bumps golang.org/x/net from 0.11.0 to 0.12.0 ([#1328](https://github.com/cloudflare/cloudflare-go/issues/1328))
diff --git a/device_posture_rule.go b/device_posture_rule.go
index 827b82670..56d143e8e 100644
--- a/device_posture_rule.go
+++ b/device_posture_rule.go
@@ -187,12 +187,6 @@ type DevicePostureRuleInput struct {
 	CountOperator    string   `json:"countOperator,omitempty"`
 	TotalScore       string   `json:"total_score,omitempty"`
 	ScoreOperator    string   `json:"scoreOperator,omitempty"`
-	CertificateID    string   `json:"certificate_id,omitempty"`
-	CommonName       string   `json:"cn,omitempty"`
-	ActiveThreats    int      `json:"active_threats,omitempty"`
-	NetworkStatus    string   `json:"network_status,omitempty"`
-	Infected         bool     `json:"infected,omitempty"`
-	IsActive         bool     `json:"is_active,omitempty"`
 }
 
 // DevicePostureRuleListResponse represents the response from the list
diff --git a/images.go b/images.go
index 59209ad1f..b93b2f46d 100644
--- a/images.go
+++ b/images.go
@@ -37,7 +37,6 @@ type Image struct {
 // UploadImageParams is the data required for an Image Upload request.
 type UploadImageParams struct {
 	File              io.ReadCloser
-	URL               string
 	Name              string
 	RequireSignedURLs bool
 	Metadata          map[string]interface{}
@@ -46,43 +45,33 @@ type UploadImageParams struct {
 // write writes the image upload data to a multipart writer, so
 // it can be used in an HTTP request.
 func (b UploadImageParams) write(mpw *multipart.Writer) error {
-	if b.File == nil && b.URL == "" {
-		return errors.New("a file or url to upload must be specified")
+	if b.File == nil {
+		return errors.New("a file to upload must be specified")
 	}
-
-	if b.File != nil {
-		name := b.Name
-		part, err := mpw.CreateFormFile("file", name)
-		if err != nil {
-			return err
-		}
-		_, err = io.Copy(part, b.File)
-		if err != nil {
-			_ = b.File.Close()
-			return err
-		}
-		_ = b.File.Close()
+	name := b.Name
+	part, err := mpw.CreateFormFile("file", name)
+	if err != nil {
+		return err
 	}
-
-	if b.URL != "" {
-		err := mpw.WriteField("url", b.URL)
-		if err != nil {
-			return err
-		}
+	_, err = io.Copy(part, b.File)
+	if err != nil {
+		_ = b.File.Close()
+		return err
 	}
+	_ = b.File.Close()
 
 	// According to the Cloudflare docs, this field defaults to false.
 	// For simplicity, we will only send it if the value is true, however
 	// if the default is changed to true, this logic will need to be updated.
 	if b.RequireSignedURLs {
-		err := mpw.WriteField("requireSignedURLs", "true")
+		err = mpw.WriteField("requireSignedURLs", "true")
 		if err != nil {
 			return err
 		}
 	}
 
 	if b.Metadata != nil {
-		part, err := mpw.CreateFormField("metadata")
+		part, err = mpw.CreateFormField("metadata")
 		if err != nil {
 			return err
 		}
@@ -162,10 +151,6 @@ func (api *API) UploadImage(ctx context.Context, rc *ResourceContainer, params U
 		return Image{}, ErrRequiredAccountLevelResourceContainer
 	}
 
-	if params.File != nil && params.URL != "" {
-		return Image{}, errors.New("file and url uploads are mutually exclusive and can only be performed individually")
-	}
-
 	uri := fmt.Sprintf("/accounts/%s/images/v1", rc.Identifier)
 
 	body := &bytes.Buffer{}
diff --git a/load_balancing.go b/load_balancing.go
index 3841940ba..4f6422d07 100644
--- a/load_balancing.go
+++ b/load_balancing.go
@@ -253,21 +253,17 @@ type LocationStrategy struct {
 // LoadBalancerRuleOverridesSessionAffinityAttrs mimics SessionAffinityAttributes without the
 // DrainDuration field as that field can not be overwritten via rules.
 type LoadBalancerRuleOverridesSessionAffinityAttrs struct {
-	SameSite             string   `json:"samesite,omitempty"`
-	Secure               string   `json:"secure,omitempty"`
-	ZeroDowntimeFailover string   `json:"zero_downtime_failover,omitempty"`
-	Headers              []string `json:"headers,omitempty"`
-	RequireAllHeaders    *bool    `json:"require_all_headers,omitempty"`
+	SameSite             string `json:"samesite,omitempty"`
+	Secure               string `json:"secure,omitempty"`
+	ZeroDowntimeFailover string `json:"zero_downtime_failover,omitempty"`
 }
 
-// SessionAffinityAttributes represents additional configuration options for session affinity.
+// SessionAffinityAttributes represents the fields used to set attributes in a load balancer session affinity cookie.
 type SessionAffinityAttributes struct {
-	SameSite             string   `json:"samesite,omitempty"`
-	Secure               string   `json:"secure,omitempty"`
-	DrainDuration        int      `json:"drain_duration,omitempty"`
-	ZeroDowntimeFailover string   `json:"zero_downtime_failover,omitempty"`
-	Headers              []string `json:"headers,omitempty"`
-	RequireAllHeaders    bool     `json:"require_all_headers,omitempty"`
+	SameSite             string `json:"samesite,omitempty"`
+	Secure               string `json:"secure,omitempty"`
+	DrainDuration        int    `json:"drain_duration,omitempty"`
+	ZeroDowntimeFailover string `json:"zero_downtime_failover,omitempty"`
 }
 
 // LoadBalancerOriginHealth represents the health of the origin.
diff --git a/regional_tiered_cache.go b/regional_tiered_cache.go
deleted file mode 100644
index 31471178a..000000000
--- a/regional_tiered_cache.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package cloudflare
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"time"
-)
-
-// RegionalTieredCache is the structure of the API object for the regional tiered cache
-// setting.
-type RegionalTieredCache struct {
-	ID         string    `json:"id,omitempty"`
-	ModifiedOn time.Time `json:"modified_on,omitempty"`
-	Value      string    `json:"value"`
-}
-
-// RegionalTieredCacheDetailsResponse is the API response for the regional tiered cache
-// setting.
-type RegionalTieredCacheDetailsResponse struct {
-	Result RegionalTieredCache `json:"result"`
-	Response
-}
-
-type zoneRegionalTieredCacheSingleResponse struct {
-	Response
-	Result RegionalTieredCache `json:"result"`
-}
-
-type GetRegionalTieredCacheParams struct{}
-
-type UpdateRegionalTieredCacheParams struct {
-	Value string `json:"value"`
-}
-
-// GetRegionalTieredCache returns information about the current regional tiered
-// cache settings.
-//
-// API reference: https://developers.cloudflare.com/api/operations/zone-cache-settings-get-regional-tiered-cache-setting
-func (api *API) GetRegionalTieredCache(ctx context.Context, rc *ResourceContainer, params GetRegionalTieredCacheParams) (RegionalTieredCache, error) {
-	if rc.Level != ZoneRouteLevel {
-		return RegionalTieredCache{}, ErrRequiredZoneLevelResourceContainer
-	}
-
-	uri := fmt.Sprintf("/%s/%s/cache/regional_tiered_cache", rc.Level, rc.Identifier)
-
-	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
-	if err != nil {
-		return RegionalTieredCache{}, err
-	}
-
-	var RegionalTieredCacheDetailsResponse RegionalTieredCacheDetailsResponse
-	err = json.Unmarshal(res, &RegionalTieredCacheDetailsResponse)
-	if err != nil {
-		return RegionalTieredCache{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
-	}
-	return RegionalTieredCacheDetailsResponse.Result, nil
-}
-
-// UpdateRegionalTieredCache updates the regional tiered cache setting for a
-// zone.
-//
-// API reference: https://developers.cloudflare.com/api/operations/zone-cache-settings-change-regional-tiered-cache-setting
-func (api *API) UpdateRegionalTieredCache(ctx context.Context, rc *ResourceContainer, params UpdateRegionalTieredCacheParams) (RegionalTieredCache, error) {
-	if rc.Level != ZoneRouteLevel {
-		return RegionalTieredCache{}, ErrRequiredZoneLevelResourceContainer
-	}
-
-	uri := fmt.Sprintf("/%s/%s/cache/regional_tiered_cache", rc.Level, rc.Identifier)
-
-	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
-	if err != nil {
-		return RegionalTieredCache{}, err
-	}
-
-	response := &zoneRegionalTieredCacheSingleResponse{}
-	err = json.Unmarshal(res, &response)
-	if err != nil {
-		return RegionalTieredCache{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
-	}
-
-	return response.Result, nil
-}
diff --git a/teams_accounts.go b/teams_accounts.go
index 7667a155b..25a2c7eb2 100644
--- a/teams_accounts.go
+++ b/teams_accounts.go
@@ -36,12 +36,13 @@ type TeamsConfiguration struct {
 }
 
 type TeamsAccountSettings struct {
-	Antivirus        *TeamsAntivirus   `json:"antivirus,omitempty"`
-	TLSDecrypt       *TeamsTLSDecrypt  `json:"tls_decrypt,omitempty"`
-	ActivityLog      *TeamsActivityLog `json:"activity_log,omitempty"`
-	BlockPage        *TeamsBlockPage   `json:"block_page,omitempty"`
-	BrowserIsolation *BrowserIsolation `json:"browser_isolation,omitempty"`
-	FIPS             *TeamsFIPS        `json:"fips,omitempty"`
+	Antivirus         *TeamsAntivirus         `json:"antivirus,omitempty"`
+	TLSDecrypt        *TeamsTLSDecrypt        `json:"tls_decrypt,omitempty"`
+	ActivityLog       *TeamsActivityLog       `json:"activity_log,omitempty"`
+	BlockPage         *TeamsBlockPage         `json:"block_page,omitempty"`
+	BrowserIsolation  *BrowserIsolation       `json:"browser_isolation,omitempty"`
+	FIPS              *TeamsFIPS              `json:"fips,omitempty"`
+	ProtocolDetection *TeamsProtocolDetection `json:"protocol_detection,omitempty"`
 }
 
 type BrowserIsolation struct {
@@ -62,6 +63,10 @@ type TeamsTLSDecrypt struct {
 	Enabled bool `json:"enabled"`
 }
 
+type TeamsProtocolDetection struct {
+	Enabled bool `json:"enabled"`
+}
+
 type TeamsActivityLog struct {
 	Enabled bool `json:"enabled"`
 }


Test patch:
diff --git a/device_posture_rule_test.go b/device_posture_rule_test.go
index 83d76083d..c7ba0f468 100644
--- a/device_posture_rule_test.go
+++ b/device_posture_rule_test.go
@@ -541,61 +541,6 @@ func TestDevicePostureDomainJoinedRule(t *testing.T) {
 	}
 }
 
-func TestDevicePostureClientCertificateRule(t *testing.T) {
-	setup()
-	defer teardown()
-
-	handler := 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": "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-				"schedule": "1h",
-				"expiration": "1h",
-				"type": "client_certificate",
-				"name": "My rule name",
-				"description": "My description",
-				"match": [
-					{
-						"platform": "windows"
-					}
-				],
-				"input": {
-					"certificate_id": "d2c04b78-3ba2-4294-8efa-4e85aef0777f",
-					"cn": "example.com"
-				}
-			}
-		}
-		`)
-	}
-
-	want := DevicePostureRule{
-		ID:          "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		Name:        "My rule name",
-		Description: "My description",
-		Type:        "client_certificate",
-		Schedule:    "1h",
-		Expiration:  "1h",
-		Match:       []DevicePostureRuleMatch{{Platform: "windows"}},
-		Input: DevicePostureRuleInput{
-			CertificateID: "d2c04b78-3ba2-4294-8efa-4e85aef0777f",
-			CommonName:    "example.com",
-		},
-	}
-
-	mux.HandleFunc("/accounts/"+testAccountID+"/devices/posture/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
-
-	actual, err := client.DevicePostureRule(context.Background(), testAccountID, "480f4f69-1a28-4fdd-9240-1ed29f0ac1db")
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
-	}
-}
-
 func TestCreateDevicePostureRule(t *testing.T) {
 	setup()
 	defer teardown()
diff --git a/images_test.go b/images_test.go
index 43cd8ad34..3640d9f31 100644
--- a/images_test.go
+++ b/images_test.go
@@ -96,61 +96,6 @@ func TestUploadImage(t *testing.T) {
 	}
 }
 
-func TestUploadImageByUrl(t *testing.T) {
-	setup()
-	defer teardown()
-
-	handler := func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
-
-		u, err := parseImageMultipartUpload(r)
-		if !assert.NoError(t, err) {
-			w.WriteHeader(http.StatusBadRequest)
-			return
-		}
-		assert.Equal(t, u.RequireSignedURLs, true)
-		assert.Equal(t, u.Metadata, map[string]interface{}{"meta": "metaID"})
-		assert.Equal(t, u.Url, "https://www.images-elsewhere.com/avatar.png")
-
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": {
-				"id": "ZxR0pLaXRldlBtaFhhO2FiZGVnaA",
-				"filename": "avatar.png",
-				"metadata": {
-					"meta": "metaID"
-				},
-				"requireSignedURLs": true,
-				"variants": [
-					"https://imagedelivery.net/MTt4OTd0b0w5aj/ZxR0pLaXRldlBtaFhhO2FiZGVnaA/hero",
-					"https://imagedelivery.net/MTt4OTd0b0w5aj/ZxR0pLaXRldlBtaFhhO2FiZGVnaA/original",
-					"https://imagedelivery.net/MTt4OTd0b0w5aj/ZxR0pLaXRldlBtaFhhO2FiZGVnaA/thumbnail"
-				],
-				"uploaded": "2014-01-02T02:20:00Z"
-			}
-		}
-		`)
-	}
-
-	mux.HandleFunc("/accounts/"+testAccountID+"/images/v1", handler)
-	want := expectedImageStruct
-
-	actual, err := client.UploadImage(context.Background(), AccountIdentifier(testAccountID), UploadImageParams{
-		URL:               "https://www.images-elsewhere.com/avatar.png",
-		RequireSignedURLs: true,
-		Metadata: map[string]interface{}{
-			"meta": "metaID",
-		},
-	})
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
-	}
-}
-
 func TestUpdateImage(t *testing.T) {
 	setup()
 	defer teardown()
@@ -252,20 +197,6 @@ func TestCreateImageDirectUploadURL(t *testing.T) {
 	}
 }
 
-func TestCreateImageConflictingTypes(t *testing.T) {
-	setup()
-	defer teardown()
-
-	_, err := client.UploadImage(context.Background(), AccountIdentifier(testAccountID), UploadImageParams{
-		URL: "https://example.com/foo.jpg",
-		File: fakeFile{
-			Buffer: bytes.NewBufferString("this is definitely an image"),
-		},
-	})
-
-	assert.Error(t, err)
-}
-
 func TestCreateImageDirectUploadURLV2(t *testing.T) {
 	setup()
 	defer teardown()
@@ -456,7 +387,6 @@ type imageMultipartUpload struct {
 	// this is for testing, never read an entire file into memory,
 	// especially when being done on a per-http request basis.
 	File              []byte
-	Url               string
 	RequireSignedURLs bool
 	Metadata          map[string]interface{}
 }
@@ -488,27 +418,15 @@ func parseImageMultipartUpload(r *http.Request) (imageMultipartUpload, error) {
 		}
 	}
 
-	if _, ok := r.MultipartForm.Value["url"]; ok {
-		urlBytes, err := getImageFormValue(r, "url")
-		if err != nil {
-			if !strings.HasPrefix(err.Error(), "no value found for key") {
-				return u, err
-			}
-		}
-		if urlBytes != nil {
-			u.Url = string(urlBytes)
-		}
-	} else {
-		f, _, err := r.FormFile("file")
-		if err != nil {
-			return u, err
-		}
-		defer f.Close()
+	f, _, err := r.FormFile("file")
+	if err != nil {
+		return u, err
+	}
+	defer f.Close()
 
-		u.File, err = io.ReadAll(f)
-		if err != nil {
-			return u, err
-		}
+	u.File, err = io.ReadAll(f)
+	if err != nil {
+		return u, err
 	}
 
 	return u, nil
diff --git a/regional_tiered_cache_test.go b/regional_tiered_cache_test.go
deleted file mode 100644
index df74f3bfe..000000000
--- a/regional_tiered_cache_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package cloudflare
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-)
-
-var regionalTieredCacheTimestampString = "2019-02-20T22:37:07.107449Z"
-var regionalTieredCacheTimestamp, _ = time.Parse(time.RFC3339Nano, regionalTieredCacheTimestampString)
-
-func TestRegionalTieredCache(t *testing.T) {
-	setup()
-	defer teardown()
-
-	handler := 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": "regional_tiered_cache",
-				"value": "on",
-				"modified_on": "%s"
-			}
-		}
-		`, regionalTieredCacheTimestampString)
-	}
-
-	mux.HandleFunc("/zones/"+testZoneID+"/cache/regional_tiered_cache", handler)
-	want := RegionalTieredCache{
-		ID:         "regional_tiered_cache",
-		Value:      "on",
-		ModifiedOn: regionalTieredCacheTimestamp,
-	}
-
-	actual, err := client.GetRegionalTieredCache(
-		context.Background(),
-		ZoneIdentifier(testZoneID),
-		GetRegionalTieredCacheParams{},
-	)
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
-	}
-}
-
-func TestUpdateRegionalTieredCache(t *testing.T) {
-	setup()
-	defer teardown()
-
-	handler := func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)
-		w.Header().Set("content-type", "application/json")
-		fmt.Fprintf(w, `{
-			"success": true,
-			"errors": [],
-			"messages": [],
-			"result": {
-				"id": "regional_tiered_cache",
-				"value": "off",
-				"modified_on": "%s"
-			}
-		}
-		`, regionalTieredCacheTimestampString)
-	}
-
-	mux.HandleFunc("/zones/"+testZoneID+"/cache/regional_tiered_cache", handler)
-	want := RegionalTieredCache{
-		ID:         "regional_tiered_cache",
-		Value:      "off",
-		ModifiedOn: regionalTieredCacheTimestamp,
-	}
-
-	actual, err := client.UpdateRegionalTieredCache(
-		context.Background(),
-		ZoneIdentifier(testZoneID),
-		UpdateRegionalTieredCacheParams{Value: "off"},
-	)
-
-	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
-	}
-}
diff --git a/teams_accounts_test.go b/teams_accounts_test.go
index 174121735..c1dfe4be4 100644
--- a/teams_accounts_test.go
+++ b/teams_accounts_test.go
@@ -59,6 +59,9 @@ func TestTeamsAccountConfiguration(t *testing.T) {
 					"tls_decrypt": {
 						"enabled": true
 					},
+					"protocol_detection": {
+						"enabled": true
+					},
 					"fips": {
 						"tls": true
 					},
@@ -88,10 +91,11 @@ func TestTeamsAccountConfiguration(t *testing.T) {
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, actual.Settings, TeamsAccountSettings{
-			Antivirus:   &TeamsAntivirus{EnabledDownloadPhase: true},
-			ActivityLog: &TeamsActivityLog{Enabled: true},
-			TLSDecrypt:  &TeamsTLSDecrypt{Enabled: true},
-			FIPS:        &TeamsFIPS{TLS: true},
+			Antivirus:         &TeamsAntivirus{EnabledDownloadPhase: true},
+			ActivityLog:       &TeamsActivityLog{Enabled: true},
+			TLSDecrypt:        &TeamsTLSDecrypt{Enabled: true},
+			ProtocolDetection: &TeamsProtocolDetection{Enabled: true},
+			FIPS:              &TeamsFIPS{TLS: true},
 
 			BlockPage: &TeamsBlockPage{
 				Enabled:         BoolPtr(true),
@@ -129,6 +133,9 @@ func TestTeamsAccountUpdateConfiguration(t *testing.T) {
 					},
 					"activity_log": {
 						"enabled": true
+					},
+					"protocol_detection": {
+						"enabled": true
 					}
 				}
 			}
@@ -137,9 +144,10 @@ func TestTeamsAccountUpdateConfiguration(t *testing.T) {
 	}
 
 	settings := TeamsAccountSettings{
-		Antivirus:   &TeamsAntivirus{EnabledDownloadPhase: false},
-		ActivityLog: &TeamsActivityLog{Enabled: true},
-		TLSDecrypt:  &TeamsTLSDecrypt{Enabled: true},
+		Antivirus:         &TeamsAntivirus{EnabledDownloadPhase: false},
+		ActivityLog:       &TeamsActivityLog{Enabled: true},
+		TLSDecrypt:        &TeamsTLSDecrypt{Enabled: true},
+		ProtocolDetection: &TeamsProtocolDetection{Enabled: true},
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/gateway/configuration", handler)