Repository: cloudflare/cloudflare-go (go)

Issue:
Device policies
### Current cloudflare-go version

0.75

### Description

Could you please add support for getting a list of []DeviceSettingsPolicy in some method like ListDeviceSettingsPolicies into cloudflare-go/devices_policy.go file?




### Use cases

currently there's no way to list existing device settings policies, though it's available via https://dash.cloudflare.com/api/v4/accounts/{account_id}/devices/policies

thus it'll be possible to add support of generating tf files for all existing policies, not just by id (e.g in cf-terraforming product)

### Potential cloudflare-go usage

Something like

```go

type DeviceSettingsPoliciesResponse struct {
	Response
	Result []DeviceSettingsPolicy `json:"result"`
}

func (api *API) ListDeviceSettingsPolicies(ctx context.Context, accountID string) ([]DeviceSettingsPolicy, error) {
	uri := fmt.Sprintf("/accounts/%s/devices/policies", accountID)

	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return []DeviceSettingsPolicy{}, err
	}

	var deviceSettingsPoliciesResponse DeviceSettingsPoliciesResponse
	err = json.Unmarshal(res, &deviceSettingsPoliciesResponse)
	if err != nil {
		return []DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return deviceSettingsPoliciesResponse.Result, nil
}
```


### References

_No response_

Pull request description:
add ListDeviceSettingsPolicies
## Description
Resolves #1381 
Adds a method to list device settings policies.

## Has your change been tested?
Added 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.
- [ ] My change requires a change to the documentation.
- [ ] 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.
  - The documentation doesn't list  the pagination parameters in the request but does show them  in `result_info` for responses. So I'm assuming they follow the existing conventions.





Patch:
diff --git a/.changelog/1433.txt b/.changelog/1433.txt
new file mode 100644
index 000000000..b8cbacb05
--- /dev/null
+++ b/.changelog/1433.txt
@@ -0,0 +1,43 @@
+```release-note:breaking-change
+devices_policy: `UpdateDeviceClientCertificatesZone` is renamed to `UpdateDeviceClientCertificates` with updated method signatures
+```
+
+```release-note:breaking-change
+devices_policy: `GetDeviceClientCertificatesZone` is renamed to `GetDeviceClientCertificates` with updated method signatures
+```
+
+```release-note:breaking-change
+devices_policy: `DeviceClientCertificates` is renamed to `DeviceClientCertificates`
+```
+
+```release-note:breaking-change
+devices_policy: `GetDeviceClientCertificates` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `CreateDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `UpdateDefaultDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `UpdateDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `DeleteDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `GetDefaultDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:breaking-change
+devices_policy: `GetDeviceSettingsPolicy` is updated with method signatures matching the library conventions
+```
+
+```release-note:enhancement
+devices_policy: Add support for listing device settings policies
+```
diff --git a/devices_policy.go b/devices_policy.go
index 77eaf112d..c662ecb42 100644
--- a/devices_policy.go
+++ b/devices_policy.go
@@ -12,8 +12,8 @@ type Enabled struct {
 	Enabled bool `json:"enabled"`
 }
 
-// DeviceClientCertificatesZone identifies if the zero trust zone is configured for an account.
-type DeviceClientCertificatesZone struct {
+// DeviceClientCertificates identifies if the zero trust zone is configured for an account.
+type DeviceClientCertificates struct {
 	Response
 	Result Enabled
 }
@@ -26,6 +26,8 @@ const (
 	proxy          ServiceMode = "proxy"
 	postureOnly    ServiceMode = "posture_only"
 	warpTunnelOnly ServiceMode = "warp_tunnel_only"
+
+	listDeviceSettingsPoliciesDefaultPageSize = 20
 )
 
 type ServiceModeV2 struct {
@@ -67,7 +69,44 @@ type DeleteDeviceSettingsPolicyResponse struct {
 	Result []DeviceSettingsPolicy
 }
 
-type DeviceSettingsPolicyRequest struct {
+type CreateDeviceSettingsPolicyParams struct {
+	DisableAutoFallback *bool          `json:"disable_auto_fallback,omitempty"`
+	CaptivePortal       *int           `json:"captive_portal,omitempty"`
+	AllowModeSwitch     *bool          `json:"allow_mode_switch,omitempty"`
+	SwitchLocked        *bool          `json:"switch_locked,omitempty"`
+	AllowUpdates        *bool          `json:"allow_updates,omitempty"`
+	AutoConnect         *int           `json:"auto_connect,omitempty"`
+	AllowedToLeave      *bool          `json:"allowed_to_leave,omitempty"`
+	SupportURL          *string        `json:"support_url,omitempty"`
+	ServiceModeV2       *ServiceModeV2 `json:"service_mode_v2,omitempty"`
+	Precedence          *int           `json:"precedence,omitempty"`
+	Name                *string        `json:"name,omitempty"`
+	Match               *string        `json:"match,omitempty"`
+	Enabled             *bool          `json:"enabled,omitempty"`
+	ExcludeOfficeIps    *bool          `json:"exclude_office_ips"`
+	Description         *string        `json:"description,omitempty"`
+}
+
+type UpdateDefaultDeviceSettingsPolicyParams struct {
+	DisableAutoFallback *bool          `json:"disable_auto_fallback,omitempty"`
+	CaptivePortal       *int           `json:"captive_portal,omitempty"`
+	AllowModeSwitch     *bool          `json:"allow_mode_switch,omitempty"`
+	SwitchLocked        *bool          `json:"switch_locked,omitempty"`
+	AllowUpdates        *bool          `json:"allow_updates,omitempty"`
+	AutoConnect         *int           `json:"auto_connect,omitempty"`
+	AllowedToLeave      *bool          `json:"allowed_to_leave,omitempty"`
+	SupportURL          *string        `json:"support_url,omitempty"`
+	ServiceModeV2       *ServiceModeV2 `json:"service_mode_v2,omitempty"`
+	Precedence          *int           `json:"precedence,omitempty"`
+	Name                *string        `json:"name,omitempty"`
+	Match               *string        `json:"match,omitempty"`
+	Enabled             *bool          `json:"enabled,omitempty"`
+	ExcludeOfficeIps    *bool          `json:"exclude_office_ips"`
+	Description         *string        `json:"description,omitempty"`
+}
+
+type UpdateDeviceSettingsPolicyParams struct {
+	PolicyID            *string        `json:"-"`
 	DisableAutoFallback *bool          `json:"disable_auto_fallback,omitempty"`
 	CaptivePortal       *int           `json:"captive_portal,omitempty"`
 	AllowModeSwitch     *bool          `json:"allow_mode_switch,omitempty"`
@@ -85,14 +124,36 @@ type DeviceSettingsPolicyRequest struct {
 	Description         *string        `json:"description,omitempty"`
 }
 
+type ListDeviceSettingsPoliciesResponse struct {
+	Response
+	ResultInfo ResultInfo             `json:"result_info"`
+	Result     []DeviceSettingsPolicy `json:"result"`
+}
+
+type UpdateDeviceClientCertificatesParams struct {
+	Enabled *bool `json:"enabled"`
+}
+
+type GetDeviceClientCertificatesParams struct{}
+
+type GetDefaultDeviceSettingsPolicyParams struct{}
+
+type GetDeviceSettingsPolicyParams struct {
+	PolicyID *string `json:"-"`
+}
+
 // UpdateDeviceClientCertificates controls the zero trust zone used to provision client certificates.
 //
 // API reference: https://api.cloudflare.com/#device-client-certificates
-func (api *API) UpdateDeviceClientCertificatesZone(ctx context.Context, zoneID string, enable bool) (DeviceClientCertificatesZone, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", ZoneRouteRoot, zoneID)
+func (api *API) UpdateDeviceClientCertificates(ctx context.Context, rc *ResourceContainer, params UpdateDeviceClientCertificatesParams) (DeviceClientCertificates, error) {
+	if rc.Level != ZoneRouteLevel {
+		return DeviceClientCertificates{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", rc.Level, rc.Identifier)
 
-	result := DeviceClientCertificatesZone{}
-	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, Enabled{enable})
+	result := DeviceClientCertificates{Result: Enabled{false}}
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
 		return result, err
 	}
@@ -104,13 +165,18 @@ func (api *API) UpdateDeviceClientCertificatesZone(ctx context.Context, zoneID s
 	return result, err
 }
 
-// GetDeviceClientCertificatesZone controls the zero trust zone used to provision client certificates.
+// GetDeviceClientCertificates controls the zero trust zone used to provision
+// client certificates.
 //
 // API reference: https://api.cloudflare.com/#device-client-certificates
-func (api *API) GetDeviceClientCertificatesZone(ctx context.Context, zoneID string) (DeviceClientCertificatesZone, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", ZoneRouteRoot, zoneID)
+func (api *API) GetDeviceClientCertificates(ctx context.Context, rc *ResourceContainer, params GetDeviceClientCertificatesParams) (DeviceClientCertificates, error) {
+	if rc.Level != ZoneRouteLevel {
+		return DeviceClientCertificates{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
 
-	result := DeviceClientCertificatesZone{}
+	uri := fmt.Sprintf("/%s/%s/devices/policy/certificates", rc.Level, rc.Identifier)
+
+	result := DeviceClientCertificates{}
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return result, err
@@ -123,116 +189,181 @@ func (api *API) GetDeviceClientCertificatesZone(ctx context.Context, zoneID stri
 	return result, err
 }
 
-// CreateDeviceSettingsPolicy creates a settings policy against devices that match the policy
+// CreateDeviceSettingsPolicy creates a settings policy against devices that
+// match the policy.
 //
 // API reference: https://api.cloudflare.com/#devices-create-device-settings-policy
-func (api *API) CreateDeviceSettingsPolicy(ctx context.Context, accountID string, req DeviceSettingsPolicyRequest) (DeviceSettingsPolicyResponse, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy", AccountRouteRoot, accountID)
+func (api *API) CreateDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params CreateDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
 
 	result := DeviceSettingsPolicyResponse{}
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, req)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
-		return result, err
+		return DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
 }
 
 // UpdateDefaultDeviceSettingsPolicy updates the default settings policy for an account
 //
 // API reference: https://api.cloudflare.com/#devices-update-default-device-settings-policy
-func (api *API) UpdateDefaultDeviceSettingsPolicy(ctx context.Context, accountID string, req DeviceSettingsPolicyRequest) (DeviceSettingsPolicyResponse, error) {
+func (api *API) UpdateDefaultDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params UpdateDefaultDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
 	result := DeviceSettingsPolicyResponse{}
-	uri := fmt.Sprintf("/%s/%s/devices/policy", AccountRouteRoot, accountID)
-	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, req)
+	uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
-		return result, err
+		return DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
 }
 
 // UpdateDeviceSettingsPolicy updates a settings policy
 //
 // API reference: https://api.cloudflare.com/#devices-update-device-settings-policy
-func (api *API) UpdateDeviceSettingsPolicy(ctx context.Context, accountID, policyID string, req DeviceSettingsPolicyRequest) (DeviceSettingsPolicyResponse, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", AccountRouteRoot, accountID, policyID)
+func (api *API) UpdateDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params UpdateDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, *params.PolicyID)
 
 	result := DeviceSettingsPolicyResponse{}
-	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, req)
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
-		return result, err
+		return DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
 }
 
 // DeleteDeviceSettingsPolicy deletes a settings policy and returns a list
-// of all of the other policies in the account
+// of all of the other policies in the account.
 //
 // API reference: https://api.cloudflare.com/#devices-delete-device-settings-policy
-func (api *API) DeleteDeviceSettingsPolicy(ctx context.Context, accountID, policyID string) (DeleteDeviceSettingsPolicyResponse, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", AccountRouteRoot, accountID, policyID)
+func (api *API) DeleteDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, policyID string) ([]DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return []DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, policyID)
 
 	result := DeleteDeviceSettingsPolicyResponse{}
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
-		return result, err
+		return []DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return []DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
 }
 
-// GetDefaultDeviceSettings gets the default device settings policy
+// GetDefaultDeviceSettings gets the default device settings policy.
 //
 // API reference: https://api.cloudflare.com/#devices-get-default-device-settings-policy
-func (api *API) GetDefaultDeviceSettingsPolicy(ctx context.Context, accountID string) (DeviceSettingsPolicyResponse, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy", AccountRouteRoot, accountID)
+func (api *API) GetDefaultDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params GetDefaultDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy", rc.Level, rc.Identifier)
 
 	result := DeviceSettingsPolicyResponse{}
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
-		return result, err
+		return DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
 }
 
-// GetDefaultDeviceSettings gets the device settings policy by its policyID
+// GetDefaultDeviceSettings gets the device settings policy by its policyID.
 //
 // API reference: https://api.cloudflare.com/#devices-get-device-settings-policy-by-id
-func (api *API) GetDeviceSettingsPolicy(ctx context.Context, accountID, policyID string) (DeviceSettingsPolicyResponse, error) {
-	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", AccountRouteRoot, accountID, policyID)
+func (api *API) GetDeviceSettingsPolicy(ctx context.Context, rc *ResourceContainer, params GetDeviceSettingsPolicyParams) (DeviceSettingsPolicy, error) {
+	if rc.Level != AccountRouteLevel {
+		return DeviceSettingsPolicy{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
+	}
+
+	uri := fmt.Sprintf("/%s/%s/devices/policy/%s", rc.Level, rc.Identifier, *params.PolicyID)
 
 	result := DeviceSettingsPolicyResponse{}
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
-		return result, err
+		return DeviceSettingsPolicy{}, err
 	}
 
 	if err := json.Unmarshal(res, &result); err != nil {
-		return result, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DeviceSettingsPolicy{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return result, err
+	return result.Result, err
+}
+
+type ListDeviceSettingsPoliciesParams struct {
+	ResultInfo
+}
+
+// ListDeviceSettingsPolicies returns all device settings policies for an account
+//
+// API reference: https://api.cloudflare.com/#devices-list-device-settings-policies
+func (api *API) ListDeviceSettingsPolicies(ctx context.Context, rc *ResourceContainer, params ListDeviceSettingsPoliciesParams) ([]DeviceSettingsPolicy, *ResultInfo, error) {
+	autoPaginate := true
+	if params.PerPage >= 1 || params.Page >= 1 {
+		autoPaginate = false
+	}
+
+	if params.PerPage < 1 {
+		params.PerPage = listDeviceSettingsPoliciesDefaultPageSize
+	}
+
+	var policies []DeviceSettingsPolicy
+	var lastResultInfo ResultInfo
+	for {
+		uri := buildURI(fmt.Sprintf("/%s/%s/devices/policies", rc.Level, rc.Identifier), params)
+		res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+		if err != nil {
+			return nil, nil, err
+		}
+		var r ListDeviceSettingsPoliciesResponse
+		err = json.Unmarshal(res, &r)
+		if err != nil {
+			return nil, nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		}
+		policies = append(policies, r.Result...)
+		lastResultInfo = r.ResultInfo
+		params.ResultInfo = r.ResultInfo.Next()
+		if params.ResultInfo.Done() || !autoPaginate {
+			break
+		}
+	}
+	return policies, &lastResultInfo, nil
 }


Test patch:
diff --git a/devices_policy_test.go b/devices_policy_test.go
index de29cc0a6..b08e45226 100644
--- a/devices_policy_test.go
+++ b/devices_policy_test.go
@@ -150,7 +150,7 @@ var (
 	}`, deviceSettingsPolicyID, deviceSettingsPolicyMatch)
 )
 
-func TestUpdateDeviceClientCertificatesZone(t *testing.T) {
+func TestUpdateDeviceClientCertificates(t *testing.T) {
 	setup()
 	defer teardown()
 
@@ -165,7 +165,7 @@ func TestUpdateDeviceClientCertificatesZone(t *testing.T) {
 		}`)
 	}
 
-	want := DeviceClientCertificatesZone{
+	want := DeviceClientCertificates{
 		Response: Response{
 			Success:  true,
 			Errors:   nil,
@@ -176,14 +176,14 @@ func TestUpdateDeviceClientCertificatesZone(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/devices/policy/certificates", handler)
 
-	actual, err := client.UpdateDeviceClientCertificatesZone(context.Background(), testZoneID, true)
+	actual, err := client.UpdateDeviceClientCertificates(context.Background(), ZoneIdentifier(testZoneID), UpdateDeviceClientCertificatesParams{Enabled: BoolPtr(true)})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
 }
 
-func TestGetDeviceClientCertificatesZone(t *testing.T) {
+func TestGetDeviceClientCertificates(t *testing.T) {
 	setup()
 	defer teardown()
 
@@ -198,7 +198,7 @@ func TestGetDeviceClientCertificatesZone(t *testing.T) {
 		}`)
 	}
 
-	want := DeviceClientCertificatesZone{
+	want := DeviceClientCertificates{
 		Response: Response{
 			Success:  true,
 			Errors:   nil,
@@ -209,7 +209,7 @@ func TestGetDeviceClientCertificatesZone(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/devices/policy/certificates", handler)
 
-	actual, err := client.GetDeviceClientCertificatesZone(context.Background(), testZoneID)
+	actual, err := client.GetDeviceClientCertificates(context.Background(), ZoneIdentifier(testZoneID), GetDeviceClientCertificatesParams{})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -231,18 +231,9 @@ func TestCreateDeviceSettingsPolicy(t *testing.T) {
 		}`, nonDefaultDeviceSettingsPolicyJson)
 	}
 
-	want := DeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: nonDefaultDeviceSettingsPolicy,
-	}
-
 	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy", handler)
 
-	actual, err := client.CreateDeviceSettingsPolicy(context.Background(), testAccountID, DeviceSettingsPolicyRequest{
+	actual, err := client.CreateDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), CreateDeviceSettingsPolicyParams{
 		Precedence:  IntPtr(10),
 		Match:       &deviceSettingsPolicyMatch,
 		Name:        StringPtr("test"),
@@ -250,7 +241,7 @@ func TestCreateDeviceSettingsPolicy(t *testing.T) {
 	})
 
 	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
+		assert.Equal(t, nonDefaultDeviceSettingsPolicy, actual)
 	}
 }
 
@@ -269,21 +260,12 @@ func TestUpdateDefaultDeviceSettingsPolicy(t *testing.T) {
 		}`, defaultDeviceSettingsPolicyJson)
 	}
 
-	want := DeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: defaultDeviceSettingsPolicy,
-	}
-
 	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy", handler)
 
-	actual, err := client.UpdateDefaultDeviceSettingsPolicy(context.Background(), testAccountID, DeviceSettingsPolicyRequest{})
+	actual, err := client.UpdateDefaultDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), UpdateDefaultDeviceSettingsPolicyParams{})
 
 	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
+		assert.Equal(t, defaultDeviceSettingsPolicy, actual)
 	}
 }
 
@@ -303,23 +285,16 @@ func TestUpdateDeviceSettingsPolicy(t *testing.T) {
 	}
 
 	precedence := 10
-	want := DeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: nonDefaultDeviceSettingsPolicy,
-	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy/"+deviceSettingsPolicyID, handler)
 
-	actual, err := client.UpdateDeviceSettingsPolicy(context.Background(), testAccountID, deviceSettingsPolicyID, DeviceSettingsPolicyRequest{
+	actual, err := client.UpdateDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), UpdateDeviceSettingsPolicyParams{
+		PolicyID:   &deviceSettingsPolicyID,
 		Precedence: &precedence,
 	})
 
 	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
+		assert.Equal(t, nonDefaultDeviceSettingsPolicy, actual)
 	}
 }
 
@@ -338,21 +313,12 @@ func TestDeleteDeviceSettingsPolicy(t *testing.T) {
 		}`, defaultDeviceSettingsPolicyJson)
 	}
 
-	want := DeleteDeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: []DeviceSettingsPolicy{defaultDeviceSettingsPolicy},
-	}
-
 	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy/"+deviceSettingsPolicyID, handler)
 
-	actual, err := client.DeleteDeviceSettingsPolicy(context.Background(), testAccountID, deviceSettingsPolicyID)
+	actual, err := client.DeleteDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), deviceSettingsPolicyID)
 
 	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
+		assert.Equal(t, []DeviceSettingsPolicy{defaultDeviceSettingsPolicy}, actual)
 	}
 }
 
@@ -371,21 +337,12 @@ func TestGetDefaultDeviceSettings(t *testing.T) {
 		}`, defaultDeviceSettingsPolicyJson)
 	}
 
-	want := DeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: defaultDeviceSettingsPolicy,
-	}
-
 	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy", handler)
 
-	actual, err := client.GetDefaultDeviceSettingsPolicy(context.Background(), testAccountID)
+	actual, err := client.GetDefaultDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), GetDefaultDeviceSettingsPolicyParams{})
 
 	if assert.NoError(t, err) {
-		assert.Equal(t, want, actual)
+		assert.Equal(t, defaultDeviceSettingsPolicy, actual)
 	}
 }
 
@@ -404,20 +361,55 @@ func TestGetDeviceSettings(t *testing.T) {
 		}`, nonDefaultDeviceSettingsPolicyJson)
 	}
 
-	want := DeviceSettingsPolicyResponse{
-		Response: Response{
-			Success:  true,
-			Errors:   nil,
-			Messages: nil,
-		},
-		Result: nonDefaultDeviceSettingsPolicy,
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy/"+deviceSettingsPolicyID, handler)
+
+	actual, err := client.GetDeviceSettingsPolicy(context.Background(), AccountIdentifier(testAccountID), GetDeviceSettingsPolicyParams{PolicyID: &deviceSettingsPolicyID})
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, nonDefaultDeviceSettingsPolicy, actual)
 	}
+}
 
-	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policy/"+deviceSettingsPolicyID, handler)
+func TestListDeviceSettingsPolicies(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": null,
+			"messages": null,
+			"result": [%s],
+			"result_info": {
+  				"count": 1,
+  				"page": 1,
+  				"per_page": 20,
+  				"total_count": 1
+			}
+		}`, nonDefaultDeviceSettingsPolicyJson)
+	}
 
-	actual, err := client.GetDeviceSettingsPolicy(context.Background(), testAccountID, deviceSettingsPolicyID)
+	want := []DeviceSettingsPolicy{nonDefaultDeviceSettingsPolicy}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/devices/policies", handler)
+
+	actual, resultInfo, err := client.ListDeviceSettingsPolicies(context.Background(), AccountIdentifier(testAccountID), ListDeviceSettingsPoliciesParams{
+		ResultInfo: ResultInfo{
+			Page:    1,
+			PerPage: 20,
+		},
+	})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
+		assert.Equal(t, &ResultInfo{
+			Count:   1,
+			Page:    1,
+			PerPage: 20,
+			Total:   1,
+		}, resultInfo)
+		assert.Len(t, actual, 1)
 	}
 }