Repository: cloudflare/cloudflare-go
Pull request #1264 (2023-04-07 01:34:26)

Add support for pages deployment auto pagination
## Description

Adds support for auto paginate for pages deployments. Support forcing deletion of a pages deployment.
Also removed an unused type and var.

## Has your change been tested?

Updated existing tests and they pass.

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [X] 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 (api.cloudflare.com or developers.cloudflare.com) and stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/



Patch:
diff --git a/.changelog/1264.txt b/.changelog/1264.txt
new file mode 100644
index 000000000..55ed09577
--- /dev/null
+++ b/.changelog/1264.txt
@@ -0,0 +1,19 @@
+```release-note:breaking-change
+pages_deployment: add support for auto pagination
+```
+
+```release-note:enchancement
+pages_deployment: add Force to DeletePagesDeploymentParams
+```
+
+```release-note:breaking-change
+pages_deployment: change DeletePagesDeploymentParams to contain all parameters
+```
+
+```release-note:breaking-change
+pages_project: rename PagesProject to GetPagesProject
+```
+
+```release-note:breaking-change
+pages_project: change to use ResourceContainer for account ID
+```
\ No newline at end of file
diff --git a/pages_deployment.go b/pages_deployment.go
index 4eb5c8f2a..899e89100 100644
--- a/pages_deployment.go
+++ b/pages_deployment.go
@@ -62,12 +62,6 @@ type pagesDeploymentResponse struct {
 	Result PagesProjectDeployment `json:"result"`
 }
 
-type pagesDeploymentStageLogsResponse struct {
-	Response
-	Result     PagesDeploymentStageLogs `json:"result"`
-	ResultInfo `json:"result_info"`
-}
-
 type pagesDeploymentLogsResponse struct {
 	Response
 	Result     PagesDeploymentLogs `json:"result"`
@@ -75,9 +69,9 @@ type pagesDeploymentLogsResponse struct {
 }
 
 type ListPagesDeploymentsParams struct {
-	ProjectName string
+	ProjectName string `url:"-"`
 
-	PaginationOptions
+	ResultInfo
 }
 
 type GetPagesDeploymentInfoParams struct {
@@ -101,12 +95,14 @@ type GetPagesDeploymentLogsParams struct {
 }
 
 type DeletePagesDeploymentParams struct {
-	ProjectName  string
-	DeploymentID string
+	ProjectName  string `url:"-"`
+	DeploymentID string `url:"-"`
+	Force        bool   `url:"force,omitempty"`
 }
 
 type CreatePagesDeploymentParams struct {
-	ProjectName string
+	ProjectName string `json:"-"`
+	Branch      string `json:"branch,omitempty"`
 }
 
 type RetryPagesDeploymentParams struct {
@@ -122,33 +118,53 @@ type RollbackPagesDeploymentParams struct {
 var (
 	ErrMissingProjectName  = errors.New("required missing project name")
 	ErrMissingDeploymentID = errors.New("required missing deployment ID")
-	ErrMissingStageName    = errors.New("required missing stage name")
 )
 
 // ListPagesDeployments returns all deployments for a Pages project.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-get-deployments
-func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, ResultInfo, error) {
+func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, *ResultInfo, error) {
 	if rc.Identifier == "" {
-		return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingAccountID
+		return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingAccountID
 	}
 
 	if params.ProjectName == "" {
-		return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingProjectName
+		return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingProjectName
 	}
 
-	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params.PaginationOptions)
+	autoPaginate := true
+	if params.PerPage >= 1 || params.Page >= 1 {
+		autoPaginate = false
+	}
 
-	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
-	if err != nil {
-		return []PagesProjectDeployment{}, ResultInfo{}, err
+	if params.PerPage < 1 {
+		params.PerPage = 25
 	}
-	var r pagesDeploymentListResponse
-	err = json.Unmarshal(res, &r)
-	if err != nil {
-		return []PagesProjectDeployment{}, ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+
+	if params.Page < 1 {
+		params.Page = 1
 	}
-	return r.Result, r.ResultInfo, nil
+
+	var deployments []PagesProjectDeployment
+	var r pagesDeploymentListResponse
+
+	for {
+		uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params)
+		res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+		if err != nil {
+			return []PagesProjectDeployment{}, &ResultInfo{}, err
+		}
+		err = json.Unmarshal(res, &r)
+		if err != nil {
+			return []PagesProjectDeployment{}, &ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		}
+		deployments = append(deployments, r.Result...)
+		params.ResultInfo = r.ResultInfo.Next()
+		if params.Done() || !autoPaginate {
+			break
+		}
+	}
+	return deployments, &r.ResultInfo, nil
 }
 
 // GetPagesDeploymentInfo returns a deployment for a Pages project.
@@ -217,20 +233,20 @@ func (api *API) GetPagesDeploymentLogs(ctx context.Context, rc *ResourceContaine
 // DeletePagesDeployment deletes a Pages deployment.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-delete-deployment
-func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) error {
+func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, params DeletePagesDeploymentParams) error {
 	if rc.Identifier == "" {
 		return ErrMissingAccountID
 	}
 
-	if projectName == "" {
+	if params.ProjectName == "" {
 		return ErrMissingProjectName
 	}
 
-	if deploymentID == "" {
+	if params.DeploymentID == "" {
 		return ErrMissingDeploymentID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, projectName, deploymentID)
+	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, params.ProjectName, params.DeploymentID), params)
 
 	_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -253,7 +269,7 @@ func (api *API) CreatePagesDeployment(ctx context.Context, rc *ResourceContainer
 
 	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName)
 
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
 		return PagesProjectDeployment{}, err
 	}
diff --git a/pages_project.go b/pages_project.go
index 4cbbb4649..94c67b242 100644
--- a/pages_project.go
+++ b/pages_project.go
@@ -190,11 +190,46 @@ const (
 	Unbound UsageModel = "unbound"
 )
 
+type ListPagesProjectsParams struct {
+	PaginationOptions
+}
+
+type CreatePagesProjectParams struct {
+	Name                string                        `json:"name,omitempty"`
+	SubDomain           string                        `json:"subdomain"`
+	Domains             []string                      `json:"domains,omitempty"`
+	Source              *PagesProjectSource           `json:"source,omitempty"`
+	BuildConfig         PagesProjectBuildConfig       `json:"build_config"`
+	DeploymentConfigs   PagesProjectDeploymentConfigs `json:"deployment_configs"`
+	LatestDeployment    PagesProjectDeployment        `json:"latest_deployment"`
+	CanonicalDeployment PagesProjectDeployment        `json:"canonical_deployment"`
+	ProductionBranch    string                        `json:"production_branch,omitempty"`
+}
+
+type UpdatePagesProjectParams struct {
+	// `ID` is used for addressing the resource via the UI or a stable
+	// anchor whereas `Name` is used for updating the value.
+	ID                  string                        `json:"-"`
+	Name                string                        `json:"name,omitempty"`
+	SubDomain           string                        `json:"subdomain"`
+	Domains             []string                      `json:"domains,omitempty"`
+	Source              *PagesProjectSource           `json:"source,omitempty"`
+	BuildConfig         PagesProjectBuildConfig       `json:"build_config"`
+	DeploymentConfigs   PagesProjectDeploymentConfigs `json:"deployment_configs"`
+	LatestDeployment    PagesProjectDeployment        `json:"latest_deployment"`
+	CanonicalDeployment PagesProjectDeployment        `json:"canonical_deployment"`
+	ProductionBranch    string                        `json:"production_branch,omitempty"`
+}
+
 // ListPagesProjects returns all Pages projects for an account.
 //
 // API reference: https://api.cloudflare.com/#pages-project-get-projects
-func (api *API) ListPagesProjects(ctx context.Context, accountID string, pageOpts PaginationOptions) ([]PagesProject, ResultInfo, error) {
-	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects", accountID), pageOpts)
+func (api *API) ListPagesProjects(ctx context.Context, rc *ResourceContainer, params ListPagesProjectsParams) ([]PagesProject, ResultInfo, error) {
+	if rc.Identifier == "" {
+		return []PagesProject{}, ResultInfo{}, ErrMissingAccountID
+	}
+
+	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects", rc.Identifier), params)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -208,11 +243,15 @@ func (api *API) ListPagesProjects(ctx context.Context, accountID string, pageOpt
 	return r.Result, r.ResultInfo, nil
 }
 
-// PagesProject returns a single Pages project by name.
+// GetPagesProject returns a single Pages project by name.
 //
 // API reference: https://api.cloudflare.com/#pages-project-get-project
-func (api *API) PagesProject(ctx context.Context, accountID, projectName string) (PagesProject, error) {
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", accountID, projectName)
+func (api *API) GetPagesProject(ctx context.Context, rc *ResourceContainer, projectName string) (PagesProject, error) {
+	if rc.Identifier == "" {
+		return PagesProject{}, ErrMissingAccountID
+	}
+
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", rc.Identifier, projectName)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return PagesProject{}, err
@@ -228,9 +267,12 @@ func (api *API) PagesProject(ctx context.Context, accountID, projectName string)
 // CreatePagesProject creates a new Pages project in an account.
 //
 // API reference: https://api.cloudflare.com/#pages-project-create-project
-func (api *API) CreatePagesProject(ctx context.Context, accountID string, pagesProject PagesProject) (PagesProject, error) {
-	uri := fmt.Sprintf("/accounts/%s/pages/projects", accountID)
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, pagesProject)
+func (api *API) CreatePagesProject(ctx context.Context, rc *ResourceContainer, params CreatePagesProjectParams) (PagesProject, error) {
+	if rc.Identifier == "" {
+		return PagesProject{}, ErrMissingAccountID
+	}
+	uri := fmt.Sprintf("/accounts/%s/pages/projects", rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
 		return PagesProject{}, err
 	}
@@ -245,9 +287,17 @@ func (api *API) CreatePagesProject(ctx context.Context, accountID string, pagesP
 // UpdatePagesProject updates an existing Pages project.
 //
 // API reference: https://api.cloudflare.com/#pages-project-update-project
-func (api *API) UpdatePagesProject(ctx context.Context, accountID, projectName string, pagesProject PagesProject) (PagesProject, error) {
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", accountID, projectName)
-	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, pagesProject)
+func (api *API) UpdatePagesProject(ctx context.Context, rc *ResourceContainer, params UpdatePagesProjectParams) (PagesProject, error) {
+	if rc.Identifier == "" {
+		return PagesProject{}, ErrMissingAccountID
+	}
+
+	if params.ID == "" {
+		return PagesProject{}, ErrMissingIdentifier
+	}
+
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", rc.Identifier, params.ID)
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
 		return PagesProject{}, err
 	}
@@ -262,8 +312,11 @@ func (api *API) UpdatePagesProject(ctx context.Context, accountID, projectName s
 // DeletePagesProject deletes a Pages project by name.
 //
 // API reference: https://api.cloudflare.com/#pages-project-delete-project
-func (api *API) DeletePagesProject(ctx context.Context, accountID, projectName string) error {
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", accountID, projectName)
+func (api *API) DeletePagesProject(ctx context.Context, rc *ResourceContainer, projectName string) error {
+	if rc.Identifier == "" {
+		return ErrMissingAccountID
+	}
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s", rc.Identifier, projectName)
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
 		return err


Test patch:
diff --git a/pages_deployment_test.go b/pages_deployment_test.go
index 282710a0c..48ec89abb 100644
--- a/pages_deployment_test.go
+++ b/pages_deployment_test.go
@@ -11,7 +11,7 @@ import (
 )
 
 const (
-	testPagesDeplyomentResponse = `
+	testPagesDeploymentResponse = `
 	{
 		"id": "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
 		"short_id": "0012e50b",
@@ -207,44 +207,6 @@ var (
 		Status:    "success",
 	}
 
-	expectedPagesDeploymentStageLogEntries = []PagesDeploymentStageLogEntry{
-		{
-			ID:        0,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Installing dependencies",
-		},
-		{
-			ID:        1,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Verify run directory",
-		},
-		{
-			ID:        2,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Executing user command: bash test.sh",
-		},
-		{
-			ID:        3,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Finished",
-		},
-		{
-			ID:        4,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Building functions...",
-		},
-		{
-			ID:        5,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Validating asset output directory",
-		},
-		{
-			ID:        6,
-			Timestamp: &pagesDeploymentDummyTime,
-			Message:   "Parsed 2 valid header rules.",
-		},
-	}
-
 	expectedPagesDeploymentLogs = &PagesDeploymentLogs{
 		Total:                 6,
 		IncludesContainerLogs: true,
@@ -289,6 +251,8 @@ func TestListPagesDeployments(t *testing.T) {
 
 	handler := func(w http.ResponseWriter, r *http.Request) {
 		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
+		assert.Equal(t, "25", r.URL.Query().Get("per_page"))
+		assert.Equal(t, "1", r.URL.Query().Get("page"))
 
 		w.Header().Set("content-type", "application/json")
 		fmt.Fprintf(w, `{
@@ -304,7 +268,7 @@ func TestListPagesDeployments(t *testing.T) {
 				"count": 1,
 				"total_count": 1
 			  }
-		}`, testPagesDeplyomentResponse)
+		}`, testPagesDeploymentResponse)
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
@@ -319,12 +283,70 @@ func TestListPagesDeployments(t *testing.T) {
 		Total:   1,
 	}
 	actual, resultInfo, err := client.ListPagesDeployments(context.Background(), AccountIdentifier(testAccountID), ListPagesDeploymentsParams{
-		ProjectName:       "test",
-		PaginationOptions: PaginationOptions{},
+		ProjectName: "test",
+		ResultInfo:  ResultInfo{},
 	})
 	if assert.NoError(t, err) {
 		assert.Equal(t, expectedPagesDeployments, actual)
-		assert.Equal(t, expectedResultInfo, resultInfo)
+		assert.Equal(t, &expectedResultInfo, resultInfo)
+	}
+}
+
+func TestListPagesDeploymentsPagination(t *testing.T) {
+	setup()
+	defer teardown()
+	var page1Called, page2Called bool
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		page := r.URL.Query().Get("page")
+		w.Header().Set("content-type", "application/json")
+		switch page {
+		case "1":
+			page1Called = true
+			fmt.Fprintf(w, `{
+				"success": true,
+				"errors": [],
+				"messages": [],	
+				"result": [
+					%s
+				],
+				"result_info": {
+					"page": 1,
+					"per_page": 25,
+					"total_count": 26,
+					"total_pages": 2
+				  }
+			}`, testPagesDeploymentResponse)
+		case "2":
+			page2Called = true
+			fmt.Fprintf(w, `{
+				"success": true,
+				"errors": [],
+				"messages": [],	
+				"result": [
+					%s
+				],
+				"result_info": {
+					"page": 2,
+					"per_page": 25,
+					"total_count": 26,
+					"total_pages": 2
+				  }
+			}`, testPagesDeploymentResponse)
+		default:
+			assert.Failf(t, "Unexpected page number", "Expected page 1 or 2, got %s", page)
+			return
+		}
+	}
+	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
+	actual, resultInfo, err := client.ListPagesDeployments(context.Background(), AccountIdentifier(testAccountID), ListPagesDeploymentsParams{
+		ProjectName: "test",
+		ResultInfo:  ResultInfo{},
+	})
+	if assert.NoError(t, err) {
+		assert.True(t, page1Called)
+		assert.True(t, page2Called)
+		assert.Equal(t, 2, len(actual))
+		assert.Equal(t, 26, resultInfo.Total)
 	}
 }
 
@@ -341,7 +363,7 @@ func TestGetPagesDeploymentInfo(t *testing.T) {
 			"errors": [],
 			"messages": [],
 			"result": %s
-		}`, testPagesDeplyomentResponse)
+		}`, testPagesDeploymentResponse)
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)
@@ -386,7 +408,7 @@ func TestDeletePagesDeployment(t *testing.T) {
 
 	handler := func(w http.ResponseWriter, r *http.Request) {
 		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
-
+		assert.Equal(t, "true", r.URL.Query().Get("force"))
 		w.Header().Set("content-type", "application/json")
 		fmt.Fprintf(w, `{
 			"success": true,
@@ -398,7 +420,7 @@ func TestDeletePagesDeployment(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)
 
-	err := client.DeletePagesDeployment(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
+	err := client.DeletePagesDeployment(context.Background(), AccountIdentifier(testAccountID), DeletePagesDeploymentParams{ProjectName: "test", DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe", Force: true})
 	assert.NoError(t, err)
 }
 
@@ -415,7 +437,7 @@ func TestCreatePagesDeployment(t *testing.T) {
 			"errors": [],
 			"messages": [],
 			"result": %s
-		}`, testPagesDeplyomentResponse)
+		}`, testPagesDeploymentResponse)
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
@@ -442,7 +464,7 @@ func TestRetryPagesDeployment(t *testing.T) {
 			"errors": [],
 			"messages": [],
 			"result": %s
-		}`, testPagesDeplyomentResponse)
+		}`, testPagesDeploymentResponse)
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/retry", handler)
@@ -466,7 +488,7 @@ func TestRollbackPagesDeployment(t *testing.T) {
 			"errors": [],
 			"messages": [],
 			"result": %s
-		}`, testPagesDeplyomentResponse)
+		}`, testPagesDeploymentResponse)
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/rollback", handler)
diff --git a/pages_project_test.go b/pages_project_test.go
index 32d09ab57..3c4b7ecc0 100644
--- a/pages_project_test.go
+++ b/pages_project_test.go
@@ -81,8 +81,8 @@ const (
 			  }
             },
 			"d1_databases": {
-				"D1_BINDING": { 
-					"id": "a94509c6-0757-43f3-b053-474b0ab10935" 
+				"D1_BINDING": {
+					"id": "a94509c6-0757-43f3-b053-474b0ab10935"
 				}
 			},
 			"kv_namespaces": {
@@ -521,7 +521,13 @@ func TestListPagesProjects(t *testing.T) {
 		Count:   1,
 		Total:   1,
 	}
-	actual, resultInfo, err := client.ListPagesProjects(context.Background(), testAccountID, PaginationOptions{})
+
+	_, _, err := client.ListPagesProjects(context.Background(), AccountIdentifier(""), ListPagesProjectsParams{})
+	if assert.Error(t, err) {
+		assert.Equal(t, err.Error(), errMissingAccountID)
+	}
+
+	actual, resultInfo, err := client.ListPagesProjects(context.Background(), AccountIdentifier(testAccountID), ListPagesProjectsParams{})
 	if assert.NoError(t, err) {
 		assert.Equal(t, expectedPagesProjects, actual)
 		assert.Equal(t, expectedResultInfo, resultInfo)
@@ -546,7 +552,12 @@ func TestPagesProject(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/Test Pages Project", handler)
 
-	actual, err := client.PagesProject(context.Background(), testAccountID, "Test Pages Project")
+	_, err := client.GetPagesProject(context.Background(), AccountIdentifier(""), "Test Pages Project")
+	if assert.Error(t, err) {
+		assert.Equal(t, err.Error(), errMissingAccountID)
+	}
+
+	actual, err := client.GetPagesProject(context.Background(), AccountIdentifier(testAccountID), "Test Pages Project")
 	if assert.NoError(t, err) {
 		assert.Equal(t, *expectedPagesProject, actual)
 	}
@@ -570,7 +581,26 @@ func TestCreatePagesProject(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects", handler)
 
-	actual, err := client.CreatePagesProject(context.Background(), testAccountID, *expectedPagesProject)
+	params := &CreatePagesProjectParams{
+		SubDomain: "test.pages.dev",
+		Name:      "Test Pages Project",
+		Domains: []string{
+			"testdomain.com",
+			"testdomain.org",
+		},
+		CanonicalDeployment: *expectedPagesProjectDeployment,
+		BuildConfig:         *expectedPagesProjectBuildConfig,
+		DeploymentConfigs:   *expectedPagesProjectDeploymentConfigs,
+		Source:              expectedPagesProjectSource,
+		LatestDeployment:    *expectedPagesProjectDeployment,
+		ProductionBranch:    "main",
+	}
+	_, err := client.CreatePagesProject(context.Background(), AccountIdentifier(""), *params)
+	if assert.Error(t, err) {
+		assert.Equal(t, err.Error(), errMissingAccountID)
+	}
+
+	actual, err := client.CreatePagesProject(context.Background(), AccountIdentifier(testAccountID), *params)
 	if assert.NoError(t, err) {
 		assert.Equal(t, *expectedPagesProject, actual)
 	}
@@ -580,7 +610,8 @@ func TestUpdatePagesProject(t *testing.T) {
 	setup()
 	defer teardown()
 
-	updateAttributes := &PagesProject{
+	updateAttributes := &UpdatePagesProjectParams{
+		ID:   "Test Pages Project",
 		Name: "updated-project-name",
 	}
 
@@ -598,9 +629,12 @@ func TestUpdatePagesProject(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/Test Pages Project", handler)
 
-	_, err := client.UpdatePagesProject(context.Background(), testAccountID, "Test Pages Project", *updateAttributes)
+	_, err := client.UpdatePagesProject(context.Background(), AccountIdentifier(""), *updateAttributes)
+	if assert.Error(t, err) {
+		assert.Equal(t, err.Error(), errMissingAccountID)
+	}
 
-	t.Log(err)
+	_, err = client.UpdatePagesProject(context.Background(), AccountIdentifier(testAccountID), *updateAttributes)
 
 	assert.NoError(t, err)
 }
@@ -623,6 +657,11 @@ func TestDeletePagesProject(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/Test Pages Project", handler)
 
-	err := client.DeletePagesProject(context.Background(), testAccountID, "Test Pages Project")
+	err := client.DeletePagesProject(context.Background(), AccountIdentifier(""), "Test Pages Project")
+	if assert.Error(t, err) {
+		assert.Equal(t, err.Error(), errMissingAccountID)
+	}
+
+	err = client.DeletePagesProject(context.Background(), AccountIdentifier(testAccountID), "Test Pages Project")
 	assert.NoError(t, err)
 }