diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..485dee64bcf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/workers.go b/workers.go new file mode 100644 index 00000000000..08ee5cd99d8 --- /dev/null +++ b/workers.go @@ -0,0 +1,276 @@ +package cloudflare + +import ( + "encoding/json" + "github.com/pkg/errors" + "time" +) + +// WorkerRequestParams provides parameters for worker requests for both enterprise and standard requests +type WorkerRequestParams struct { + ZoneID string + ScriptName string +} + +// WorkerRoute aka filters are patterns used to enable or disable workers that match requests. +// +// API reference: https://api.cloudflare.com/#worker-filters-properties +type WorkerRoute struct { + ID string `json:"id,omitempty"` + Pattern string `json:"pattern"` + Enabled bool `json:"enabled"` + Script string `json:"script"` +} + +// WorkerRoutesResponse embeds Response struct and slice of WorkerRoutes +type WorkerRoutesResponse struct { + Response + Routes []WorkerRoute `json:"result"` +} + +// WorkerRouteResponse embeds Response struct and a single WorkerRoute +type WorkerRouteResponse struct { + Response + WorkerRoute `json:"result"` +} + +// WorkerScript Cloudflare Worker struct with metadata +type WorkerScript struct { + WorkerMetaData + Script string `json:"script"` +} + +// WorkerMetaData contains worker script information such as size, creation & modification dates +type WorkerMetaData struct { + ID string `json:"id,omitempty"` + ETAG string `json:"etag,omitempty"` + Size int `json:"size,omitempty"` + CreatedOn time.Time `json:"created_on,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` +} + +// WorkerListResponse wrapper struct for API response to worker script list API call +type WorkerListResponse struct { + Response + WorkerList []WorkerMetaData `json:"result"` +} + +// WorkerScriptResponse wrapper struct for API response to worker script calls +type WorkerScriptResponse struct { + Response + WorkerScript `json:"result"` +} + +// DeleteWorker deletes worker for a zone. +// +// API reference: https://api.cloudflare.com/#worker-script-delete-worker +func (api *API) DeleteWorker(requestParams *WorkerRequestParams) (WorkerScriptResponse, error) { + // if organization ID is defined and ScriptName is provided we will treat as org request + if api.organizationID != "" && requestParams.ScriptName != "" { + return api.deleteWorkerWithName(requestParams.ScriptName) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + res, err := api.makeRequest("DELETE", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DeleteWorkerWithName deletes worker for a zone. +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise +// organizationID must be specified as api option https://godoc.org/github.com/cloudflare/cloudflare-go#UsingOrganization +// +// API reference: https://api.cloudflare.com/#worker-script-delete-worker +func (api *API) deleteWorkerWithName(scriptName string) (WorkerScriptResponse, error) { + if api.organizationID == "" { + return WorkerScriptResponse{}, errors.New("organization ID required for enterprise only request") + } + uri := "/accounts/" + api.organizationID + "/workers/scripts/" + scriptName + res, err := api.makeRequest("DELETE", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DownloadWorker fetch raw script content for your worker returns []byte containing worker code js +// +// API reference: https://api.cloudflare.com/#worker-script-download-worker +func (api *API) DownloadWorker(requestParams *WorkerRequestParams) (WorkerScriptResponse, error) { + if api.organizationID != "" && requestParams.ScriptName != "" { + return api.downloadWorkerWithName(requestParams.ScriptName) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + api.headers.Add("Content-Type", "application/javascript") + res, err := api.makeRequest("GET", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + r.Script = string(res) + r.Success = true + return r, nil +} + +// DownloadWorkerWithName fetch raw script content for your worker returns string containing worker code js +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +// +// API reference: https://api.cloudflare.com/#worker-script-download-worker +func (api *API) downloadWorkerWithName(scriptName string) (WorkerScriptResponse, error) { + if api.organizationID == "" { + return WorkerScriptResponse{}, errors.New("organization ID required for enterprise only request") + } + uri := "/accounts/" + api.organizationID + "/workers/scripts/" + scriptName + api.headers.Add("Content-Type", "application/javascript") + res, err := api.makeRequest("GET", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + r.Script = string(res) + r.Success = true + return r, nil +} + +// ListWorkerScripts returns list of worker scripts for given organization +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise +// +// API reference: https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +func (api *API) ListWorkerScripts() (WorkerListResponse, error) { + if api.organizationID == "" { + return WorkerListResponse{}, errors.New("organization ID required for enterprise only request") + } + uri := "/accounts/" + api.organizationID + "/workers/scripts" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WorkerListResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerListResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerListResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// UploadWorker push raw script content for your worker +// +// API reference: https://api.cloudflare.com/#worker-script-upload-worker +func (api *API) UploadWorker(requestParams *WorkerRequestParams, data string) (WorkerScriptResponse, error) { + if api.organizationID != "" && requestParams.ScriptName != "" { + return api.uploadWorkerWithName(requestParams.ScriptName, data) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + api.headers.Add("Content-Type", "application/javascript") + res, err := api.makeRequest("PUT", uri, []byte(data)) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// UploadWorkerWithName push raw script content for your worker +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +// +// API reference: https://api.cloudflare.com/#worker-script-upload-worker +func (api *API) uploadWorkerWithName(scriptName string, data string) (WorkerScriptResponse, error) { + if api.organizationID == "" { + return WorkerScriptResponse{}, errors.New("organization ID required for enterprise only request") + } + uri := "/accounts/" + api.organizationID + "/workers/scripts/" + scriptName + api.headers.Add("Content-Type", "application/javascript") + res, err := api.makeRequest("PUT", uri, []byte(data)) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// CreateWorkerRoute creates worker route for a zone +// +// API reference: https://api.cloudflare.com/#worker-filters-create-filter +func (api *API) CreateWorkerRoute(zoneID string, route WorkerRoute) (WorkerRouteResponse, error) { + uri := "/zones/" + zoneID + "/workers/filters" + res, err := api.makeRequest("POST", uri, route) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DeleteWorkerRoute deletes worker route for a zone +// +// API reference: https://api.cloudflare.com/#worker-filters-delete-filter +func (api *API) DeleteWorkerRoute(zoneID string, routeID string) (WorkerRouteResponse, error) { + uri := "/zones/" + zoneID + "/workers/filters/" + routeID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// ListWorkerRoutes returns list of worker routes +// +// API reference: https://api.cloudflare.com/#worker-filters-list-filters +func (api *API) ListWorkerRoutes(zoneID string) (WorkerRoutesResponse, error) { + uri := "/zones/" + zoneID + "/workers/filters" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WorkerRoutesResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRoutesResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRoutesResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// UpdateWorkerRoute updates worker route for a zone. +// +// API reference: https://api.cloudflare.com/#worker-filters-update-filter +func (api *API) UpdateWorkerRoute(zoneID string, routeID string, route WorkerRoute) (WorkerRouteResponse, error) { + uri := "/zones/" + zoneID + "/workers/filters/" + routeID + res, err := api.makeRequest("PUT", uri, route) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} diff --git a/workers_example_test.go b/workers_example_test.go new file mode 100644 index 00000000000..208c60a33e3 --- /dev/null +++ b/workers_example_test.go @@ -0,0 +1,204 @@ +package cloudflare_test + +import ( + "fmt" + cloudflare "github.com/cloudflare/cloudflare-go" + "log" +) + +var ( + workerScript = "addEventListener('fetch', event => {\n event.passThroughOnException()\nevent.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n return fetch(request)\n}" +) + +func ExampleAPI_UploadWorker() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + + res, err := api.UploadWorker(&cloudflare.WorkerRequestParams{ZoneID: zoneID}, workerScript) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) + + UploadWorkerWithName() +} + +func UploadWorkerWithName() { + api, err := cloudflare.New(apiKey, user, cloudflare.UsingOrganization("foo")) + if err != nil { + log.Fatal(err) + } + + res, err := api.UploadWorker(&cloudflare.WorkerRequestParams{ScriptName: "baz"}, workerScript) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_DownloadWorker() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + + res, err := api.DownloadWorker(&cloudflare.WorkerRequestParams{ZoneID: zoneID}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) + + DownloadWorkerWithName() +} + +func DownloadWorkerWithName() { + api, err := cloudflare.New(apiKey, user, cloudflare.UsingOrganization("foo")) + if err != nil { + log.Fatal(err) + } + + res, err := api.DownloadWorker(&cloudflare.WorkerRequestParams{ScriptName: "baz"}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_DeleteWorker() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + res, err := api.DeleteWorker(&cloudflare.WorkerRequestParams{ZoneID: zoneID}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) + + DeleteWorkerWithName() +} + +func DeleteWorkerWithName() { + api, err := cloudflare.New(apiKey, user, cloudflare.UsingOrganization("foo")) + if err != nil { + log.Fatal(err) + } + + res, err := api.DeleteWorker(&cloudflare.WorkerRequestParams{ScriptName: "baz"}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_ListWorkerScripts() { + api, err := cloudflare.New(apiKey, user, cloudflare.UsingOrganization("foo")) + if err != nil { + log.Fatal(err) + } + + res, err := api.ListWorkerScripts() + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res.WorkerList) +} + +func ExampleAPI_CreateWorkerRoute() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + route := cloudflare.WorkerRoute{Pattern: "app1.example.com/*", Enabled: true} + res, err := api.CreateWorkerRoute(zoneID, route) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_UpdateWorkerRoute() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + // pull from existing list of routes to perform update on + routesResponse, err := api.ListWorkerRoutes(zoneID) + if err != nil { + log.Fatal(err) + } + route := cloudflare.WorkerRoute{Pattern: "app2.example.com/*", Enabled: true} + // update first route retrieved from the listWorkerRoutes call with details above + res, err := api.UpdateWorkerRoute(zoneID, routesResponse.Routes[0].ID, route) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_ListWorkerRoutes() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + res, err := api.ListWorkerRoutes(zoneID) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} + +func ExampleAPI_DeleteWorkerRoute() { + api, err := cloudflare.New(apiKey, user) + if err != nil { + log.Fatal(err) + } + + zoneID, err := api.ZoneIDByName(domain) + if err != nil { + log.Fatal(err) + } + // pull from existing list of routes to perform delete on + routesResponse, err := api.ListWorkerRoutes(zoneID) + if err != nil { + log.Fatal(err) + } + // delete first route retrieved from the listWorkerRoutes call + res, err := api.DeleteWorkerRoute(zoneID, routesResponse.Routes[0].ID) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v", res) +} diff --git a/workers_test.go b/workers_test.go new file mode 100644 index 00000000000..d2557f4be09 --- /dev/null +++ b/workers_test.go @@ -0,0 +1,333 @@ +package cloudflare + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "net/http" + "testing" + "time" +) + +const ( + deleteWorkerResponseData = `{ + "result": null, + "success": true, + "errors": [], + "messages": [] +}` + uploadWorkerResponseData = `{ + "result": { + "script": "addEventListener('fetch', event => {\n event.passThroughOnException()\nevent.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n return fetch(request)\n}", + "etag": "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + "size": 191, + "modified_on": "2018-06-09T15:17:01.989141Z" + }, + "success": true, + "errors": [], + "messages": [] +}` + updateWorkerRouteResponse = `{ + "result": { + "id": "e7a57d8746e74ae49c25994dadb421b1", + "pattern": "app3.example.com/*", + "enabled": true + }, + "success": true, + "errors": [], + "messages": [] +}` + createWorkerRouteResponse = `{ + "result": { + "id": "e7a57d8746e74ae49c25994dadb421b1" + }, + "success": true, + "errors": [], + "messages": [] +}` + listRouteResponseData = `{ + "result": [ + { + "id": "e7a57d8746e74ae49c25994dadb421b1", + "pattern": "app1.example.com/*", + "enabled": true + }, + { + "id": "f8b68e9857f85bf59c25994dadb421b1", + "pattern": "app2.example.com/*", + "enabled": false + } + ], + "success": true, + "errors": [], + "messages": [] +}` + listWorkersResponseData = `{ + "result": [ + { + "id": "bar", + "created_on": "2018-04-22T17:10:48.938097Z", + "modified_on": "2018-04-22T17:10:48.938097Z", + "etag": "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a" + }, + { + "id": "baz", + "created_on": "2018-04-22T17:10:48.938097Z", + "modified_on": "2018-04-22T17:10:48.938097Z", + "etag": "380dg51e97e80b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43088b" + } + ], + "success": true, + "errors": [], + "messages": [] +}` +) + +var ( + successResponse = Response{Success: true, Errors: []ResponseInfo{}, Messages: []ResponseInfo{}} + workerScript = "addEventListener('fetch', event => {\n event.passThroughOnException()\nevent.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n return fetch(request)\n}" + deleteWorkerRouteResponseData = createWorkerRouteResponse +) + +func TestWorkers_DeleteWorker(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/script", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "DELETE", r.Method, "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, deleteWorkerResponseData) + }) + res, err := client.DeleteWorker(&WorkerRequestParams{ZoneID: "foo"}) + want := WorkerScriptResponse{ + successResponse, + WorkerScript{}} + if assert.NoError(t, err) { + assert.Equal(t, want.Response, res.Response) + } +} + +func TestWorkers_DeleteWorkerWithName(t *testing.T) { + setup(UsingOrganization("foo")) + defer teardown() + + mux.HandleFunc("/accounts/foo/workers/scripts/bar", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "DELETE", r.Method, "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, deleteWorkerResponseData) + }) + res, err := client.DeleteWorker(&WorkerRequestParams{ScriptName: "bar"}) + want := WorkerScriptResponse{ + successResponse, + WorkerScript{}} + if assert.NoError(t, err) { + assert.Equal(t, want.Response, res.Response) + } +} + +func TestWorkers_DownloadWorker(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/script", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, workerScript) + }) + res, err := client.DownloadWorker(&WorkerRequestParams{ZoneID: "foo"}) + want := WorkerScriptResponse{ + successResponse, + WorkerScript{ + Script: workerScript, + }} + if assert.NoError(t, err) { + assert.Equal(t, want.Script, res.Script) + } +} + +func TestWorkers_DownloadWorkerWithName(t *testing.T) { + setup(UsingOrganization("foo")) + defer teardown() + + mux.HandleFunc("/accounts/foo/workers/scripts/bar", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, workerScript) + }) + res, err := client.DownloadWorker(&WorkerRequestParams{ScriptName: "bar"}) + want := WorkerScriptResponse{ + successResponse, + WorkerScript{ + Script: workerScript, + }} + if assert.NoError(t, err) { + assert.Equal(t, want.Script, res.Script) + } +} + +func TestWorkers_ListWorkerScripts(t *testing.T) { + setup(UsingOrganization("foo")) + defer teardown() + + mux.HandleFunc("/accounts/foo/workers/scripts", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application-json") + fmt.Fprintf(w, listWorkersResponseData) + }) + + res, err := client.ListWorkerScripts() + sampleDate, _ := time.Parse(time.RFC3339Nano, "2018-04-22T17:10:48.938097Z") + want := []WorkerMetaData{ + { + ID: "bar", + ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + CreatedOn: sampleDate, + ModifiedOn: sampleDate, + }, + { + ID: "baz", + ETAG: "380dg51e97e80b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43088b", + CreatedOn: sampleDate, + ModifiedOn: sampleDate, + }, + } + if assert.NoError(t, err) { + assert.Equal(t, want, res.WorkerList) + } + +} + +func TestWorkers_UploadWorker(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/script", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "PUT", r.Method, "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, uploadWorkerResponseData) + }) + res, err := client.UploadWorker(&WorkerRequestParams{ZoneID: "foo"}, workerScript) + formattedTime, _ := time.Parse(time.RFC3339Nano, "2018-06-09T15:17:01.989141Z") + want := WorkerScriptResponse{ + successResponse, + WorkerScript{ + Script: workerScript, + WorkerMetaData: WorkerMetaData{ + ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + Size: 191, + ModifiedOn: formattedTime, + }, + }} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } + +} + +func TestWorkers_UploadWorkerWithName(t *testing.T) { + setup(UsingOrganization("foo")) + defer teardown() + + mux.HandleFunc("/accounts/foo/workers/scripts/bar", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "PUT", r.Method, "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application/javascript") + fmt.Fprintf(w, uploadWorkerResponseData) + }) + res, err := client.UploadWorker(&WorkerRequestParams{ScriptName: "bar"}, workerScript) + formattedTime, _ := time.Parse(time.RFC3339Nano, "2018-06-09T15:17:01.989141Z") + want := WorkerScriptResponse{ + successResponse, + WorkerScript{ + Script: workerScript, + WorkerMetaData: WorkerMetaData{ + ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + Size: 191, + ModifiedOn: formattedTime, + }, + }} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } +} + +func TestWorkers_CreateWorkerRoute(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/filters", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "POST", r.Method, "Expected method 'POST', got %s", r.Method) + w.Header().Set("content-type", "application-json") + fmt.Fprintf(w, createWorkerRouteResponse) + }) + route := WorkerRoute{Pattern: "app1.example.com/*", Enabled: true} + res, err := client.CreateWorkerRoute("foo", route) + want := WorkerRouteResponse{successResponse, WorkerRoute{ID: "e7a57d8746e74ae49c25994dadb421b1"}} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } + +} + +func TestWorkers_DeleteWorkerRoute(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/filters/e7a57d8746e74ae49c25994dadb421b1", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "DELETE", r.Method, "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application-json") + fmt.Fprintf(w, deleteWorkerRouteResponseData) + }) + res, err := client.DeleteWorkerRoute("foo", "e7a57d8746e74ae49c25994dadb421b1") + want := WorkerRouteResponse{successResponse, + WorkerRoute{ + ID: "e7a57d8746e74ae49c25994dadb421b1", + }} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } + +} + +func TestWorkers_ListWorkerRoutes(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/filters", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application-json") + fmt.Fprintf(w, listRouteResponseData) + }) + + res, err := client.ListWorkerRoutes("foo") + want := WorkerRoutesResponse{successResponse, + []WorkerRoute{ + {ID: "e7a57d8746e74ae49c25994dadb421b1", Pattern: "app1.example.com/*", Enabled: true}, + {ID: "f8b68e9857f85bf59c25994dadb421b1", Pattern: "app2.example.com/*", Enabled: false}, + }, + } + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } +} + +func TestWorkers_UpdateWorkerRoute(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/zones/foo/workers/filters/e7a57d8746e74ae49c25994dadb421b1", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "PUT", r.Method, "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application-json") + fmt.Fprintf(w, updateWorkerRouteResponse) + }) + route := WorkerRoute{Pattern: "app3.example.com/*", Enabled: true} + res, err := client.UpdateWorkerRoute("foo", "e7a57d8746e74ae49c25994dadb421b1", route) + want := WorkerRouteResponse{successResponse, + WorkerRoute{ + ID: "e7a57d8746e74ae49c25994dadb421b1", + Pattern: "app3.example.com/*", + Enabled: true, + }} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } + +}