diff --git a/Makefile b/Makefile index e28ebed24..0548f01e9 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ FILES ?= ./... # List all our actual files, excluding vendor GOPKGS ?= $(shell $(GO) list $(FILES) | grep -v /vendor/) -GOFILES ?= $(shell find . -name '*.go' | grep -v /vendor/) # Tags specific for building GOTAGS ?= @@ -31,11 +30,6 @@ TEST_COMMAND ?= $(GO) test all: mod-download dev-dependencies tidy fmt fiximports test vet staticcheck semgrep ## Runs all of the required cleaning and verification targets. .PHONY: all -tidy: ## Cleans the Go module. - @echo "==> Tidying module" - @$(GO) mod tidy -.PHONY: tidy - mod-download: ## Downloads the Go module. @echo "==> Downloading Go module" @$(GO) mod download @@ -48,11 +42,41 @@ dev-dependencies: ## Downloads the necessary dev dependencies. @if [[ "$$(uname)" == 'Darwin' ]]; then brew install semgrep; fi .PHONY: dev-dependencies +tidy: ## Cleans the Go module. + @echo "==> Tidying module" + @$(GO) mod tidy +.PHONY: tidy + +fmt: ## Properly formats Go files and orders dependencies. + @echo "==> Running gofmt" + @gofmt -s -w fastly internal tools +.PHONY: fmt + +fiximports: ## Properly formats and orders imports. + @echo "==> Fixing imports" + @goimports -w fastly internal tools +.PHONY: fiximports + test: ## Runs the test suite with VCR mocks enabled. @echo "==> Testing ${NAME}" @$(TEST_COMMAND) -timeout=30s -parallel=20 -tags="${GOTAGS}" ${GOPKGS} ${TESTARGS} .PHONY: test +vet: ## Identifies common errors. + @echo "==> Running go vet" + @$(GO) vet ./... +.PHONY: vet + +staticcheck: ## Runs the staticcheck linter. + @echo "==> Running staticcheck" + @staticcheck -version + @staticcheck ./... +.PHONY: staticcheck + +semgrep: ## Run semgrep checker. + if command -v semgrep &> /dev/null; then semgrep ci --config auto --exclude-rule generic.secrets.security.detected-private-key.detected-private-key $(SEMGREP_ARGS); fi +.PHONY: semgrep + test-race: ## Runs the test suite with the -race flag to identify race conditions, if they exist. @echo "==> Testing ${NAME} (race)" @$(TEST_COMMAND) -timeout=60s -race -tags="${GOTAGS}" ${GOPKGS} ${TESTARGS} @@ -92,35 +116,9 @@ check-mod: ## A check which lists extraneous dependencies, if they exist. @$(shell pwd)/scripts/check-mod.sh .PHONY: check-mod -fiximports: ## Properly formats and orders imports. - @echo "==> Fixing imports" - @goimports -w {fastly,tools} -.PHONY: fiximports - -fmt: ## Properly formats Go files and orders dependencies. - @echo "==> Running gofmt" - @gofmt -s -w ${GOFILES} -.PHONY: fmt - -vet: ## Identifies common errors. - @echo "==> Running go vet" - @$(GO) vet ./... -.PHONY: vet - -staticcheck: ## Runs the staticcheck linter. - @echo "==> Running staticcheck" - @staticcheck -version - @staticcheck ./... -.PHONY: staticcheck - nilaway: ## Run nilaway @nilaway ./... -# Run semgrep checker. -.PHONY: semgrep -semgrep: - if command -v semgrep &> /dev/null; then semgrep ci --config auto --exclude-rule generic.secrets.security.detected-private-key.detected-private-key $(SEMGREP_ARGS); fi - .PHONY: help help: ## Prints this help menu. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fastly/client.go b/fastly/client.go index 885203e3c..f5454fcd0 100644 --- a/fastly/client.go +++ b/fastly/client.go @@ -210,6 +210,20 @@ func (c *Client) Get(p string, ro *RequestOptions) (*http.Response, error) { return c.Request("GET", p, ro) } +// GetJSON issues an HTTP GET request and indicates that the response +// should be JSON encoded. +func (c *Client) GetJSON(p string, ro *RequestOptions) (*http.Response, error) { + if ro == nil { + ro = new(RequestOptions) + } + if ro.Headers == nil { + ro.Headers = make(map[string]string) + } + ro.Parallel = true + ro.Headers["Accept"] = JSONMimeType + return c.Request("GET", p, ro) +} + // Head issues an HTTP HEAD request. func (c *Client) Head(p string, ro *RequestOptions) (*http.Response, error) { if ro == nil { diff --git a/fastly/errors.go b/fastly/errors.go index c04f0c05c..66ba83f7b 100644 --- a/fastly/errors.go +++ b/fastly/errors.go @@ -521,12 +521,17 @@ func (e *HTTPError) Error() string { } // String implements the stringer interface and returns the string representing -// the string text that includes the status code and corresponding status text. +// the error text that includes the status code and corresponding status text. func (e *HTTPError) String() string { return e.Error() } -// IsNotFound returns true if the HTTP error code is a 404, false otherwise. +// IsBadRequest returns true if the HTTP status code is 400, false otherwise. +func (e *HTTPError) IsBadRequest() bool { + return e.StatusCode == 400 +} + +// IsNotFound returns true if the HTTP status code is 404, false otherwise. func (e *HTTPError) IsNotFound() bool { return e.StatusCode == 404 } diff --git a/fastly/image_optimizer_default_settings/fixtures/disable_product.yaml b/fastly/image_optimizer_default_settings/fixtures/disable_product.yaml new file mode 100644 index 000000000..0f12ea1cb --- /dev/null +++ b/fastly/image_optimizer_default_settings/fixtures/disable_product.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"image_optimizer","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "206" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 16:56:50 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-nyc-kteb1890026-NYC + X-Timer: + - S1733590610.048385,VS0,VE454 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/enable_product.yaml b/fastly/image_optimizer_default_settings/fixtures/enable_product.yaml similarity index 52% rename from fastly/fixtures/image_optimizer_default_settings/enable_product.yaml rename to fastly/image_optimizer_default_settings/fixtures/enable_product.yaml index cd7301245..cf7820b85 100644 --- a/fastly/fixtures/image_optimizer_default_settings/enable_product.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/enable_product.yaml @@ -2,37 +2,35 @@ version: 1 interactions: - request: - body: ProductID=image_optimizer&ServiceID=kKJb5bOFI47uHeBVluGfX1 - form: - ProductID: - - image_optimizer - ServiceID: - - kKJb5bOFI47uHeBVluGfX1 + body: "null" + form: {} headers: + Accept: + - application/json Content-Type: - - application/x-www-form-urlencoded + - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/enabled-products/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 method: PUT response: body: | - {"product":{"id":"image_optimizer","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1"}} + {"product":{"id":"image_optimizer","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1"}} headers: Accept-Ranges: - bytes Cache-Control: - no-store Content-Length: - - "203" + - "206" Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:29 GMT + - Sat, 07 Dec 2024 16:56:45 GMT Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -40,15 +38,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100132-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703388.864441,VS0,VE1596 + - S1733590605.919096,VS0,VE708 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/final_reset.yaml b/fastly/image_optimizer_default_settings/fixtures/final_reset.yaml similarity index 73% rename from fastly/fixtures/image_optimizer_default_settings/final_reset.yaml rename to fastly/image_optimizer_default_settings/fixtures/final_reset.yaml index 836fce18a..7891236f7 100644 --- a/fastly/fixtures/image_optimizer_default_settings/final_reset.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/final_reset.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"nearest","webp":false,"webp_quality":85,"jpeg_type":"auto","jpeg_quality":85,"upscale":false,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:34 GMT + - Sat, 07 Dec 2024 16:56:50 GMT Fastly-Ratelimit-Remaining: - - "986" + - "972" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703394.322383,VS0,VE301 + - S1733590610.764507,VS0,VE276 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/incorrect_fetch.yaml b/fastly/image_optimizer_default_settings/fixtures/incorrect_fetch.yaml similarity index 73% rename from fastly/fixtures/image_optimizer_default_settings/incorrect_fetch.yaml rename to fastly/image_optimizer_default_settings/fixtures/incorrect_fetch.yaml index 6913269d0..1d84a4db3 100644 --- a/fastly/fixtures/image_optimizer_default_settings/incorrect_fetch.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/incorrect_fetch.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"type":"https://www.fastly.com/documentation/reference/api/services/image-optimizer-default-settings/","title":"Bad @@ -24,15 +24,15 @@ interactions: Content-Type: - application/problem+json Date: - - Tue, 14 May 2024 16:16:31 GMT + - Sat, 07 Dec 2024 16:56:46 GMT Fastly-Ratelimit-Remaining: - - "996" + - "982" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 400 Bad Request Strict-Transport-Security: @@ -40,15 +40,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703391.172090,VS0,VE235 + - S1733590607.717156,VS0,VE140 status: 400 Bad Request code: 400 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/original_fetch.yaml b/fastly/image_optimizer_default_settings/fixtures/original_fetch.yaml similarity index 69% rename from fastly/fixtures/image_optimizer_default_settings/original_fetch.yaml rename to fastly/image_optimizer_default_settings/fixtures/original_fetch.yaml index 6949a3858..c5ab0adac 100644 --- a/fastly/fixtures/image_optimizer_default_settings/original_fetch.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/original_fetch.yaml @@ -6,8 +6,8 @@ interactions: form: {} headers: User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: GET response: body: '{"resize_filter":"lanczos3","webp":false,"webp_quality":85,"jpeg_type":"auto","jpeg_quality":85,"upscale":false,"allow_video":false}' @@ -19,11 +19,11 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:29 GMT + - Sat, 07 Dec 2024 16:56:45 GMT Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -31,15 +31,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703390.548942,VS0,VE308 + - S1733590606.634206,VS0,VE144 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_full.yaml b/fastly/image_optimizer_default_settings/fixtures/set_full.yaml similarity index 73% rename from fastly/fixtures/image_optimizer_default_settings/set_full.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_full.yaml index 2302b6630..dc53223e1 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_full.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_full.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"lanczos3","webp":false,"webp_quality":85,"jpeg_type":"auto","jpeg_quality":85,"upscale":false,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:34 GMT + - Sat, 07 Dec 2024 16:56:49 GMT Fastly-Ratelimit-Remaining: - - "987" + - "973" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703394.881247,VS0,VE425 + - S1733590609.353574,VS0,VE338 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/auto.yaml b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/auto.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/auto.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/auto.yaml index c95a0be76..7a1d69de7 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/auto.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/auto.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"nearest","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:33 GMT + - Sat, 07 Dec 2024 16:56:48 GMT Fastly-Ratelimit-Remaining: - - "990" + - "976" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703393.016316,VS0,VE239 + - S1733590608.433048,VS0,VE220 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/baseline.yaml b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/baseline.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/baseline.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/baseline.yaml index 105671901..fe8a1fc6a 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/baseline.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/baseline.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"nearest","webp":true,"webp_quality":42,"jpeg_type":"baseline","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:33 GMT + - Sat, 07 Dec 2024 16:56:49 GMT Fastly-Ratelimit-Remaining: - - "989" + - "975" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703393.270782,VS0,VE295 + - S1733590609.741228,VS0,VE263 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/progressive.yaml b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/progressive.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/progressive.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/progressive.yaml index d9b62aa33..1463a5641 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_jpeg_type/progressive.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_jpeg_type/progressive.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"nearest","webp":true,"webp_quality":42,"jpeg_type":"progressive","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:33 GMT + - Sat, 07 Dec 2024 16:56:49 GMT Fastly-Ratelimit-Remaining: - - "988" + - "974" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703394.581626,VS0,VE257 + - S1733590609.047658,VS0,VE256 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bicubic.yaml b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bicubic.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bicubic.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bicubic.yaml index 065defcd6..0a855a144 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bicubic.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bicubic.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"bicubic","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:32 GMT + - Sat, 07 Dec 2024 16:56:47 GMT Fastly-Ratelimit-Remaining: - - "993" + - "979" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703392.111690,VS0,VE297 + - S1733590608.509548,VS0,VE282 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bilinear.yaml b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bilinear.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bilinear.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bilinear.yaml index 6fb86583e..55cb1d194 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/bilinear.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/bilinear.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"bilinear","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:32 GMT + - Sat, 07 Dec 2024 16:56:48 GMT Fastly-Ratelimit-Remaining: - - "992" + - "978" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703392.422974,VS0,VE295 + - S1733590608.820970,VS0,VE237 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos2.yaml b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos2.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos2.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos2.yaml index 9e40a50d2..4ab0f639b 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos2.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos2.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"lanczos2","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:32 GMT + - Sat, 07 Dec 2024 16:56:47 GMT Fastly-Ratelimit-Remaining: - - "994" + - "980" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703392.734838,VS0,VE362 + - S1733590607.203404,VS0,VE243 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos3.yaml b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos3.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos3.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos3.yaml index de4ceac21..a88b5698f 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/lanczos3.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/lanczos3.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"lanczos3","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:31 GMT + - Sat, 07 Dec 2024 16:56:47 GMT Fastly-Ratelimit-Remaining: - - "995" + - "981" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703391.424341,VS0,VE294 + - S1733590607.896997,VS0,VE230 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/nearest.yaml b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/nearest.yaml similarity index 71% rename from fastly/fixtures/image_optimizer_default_settings/set_resize_filter/nearest.yaml rename to fastly/image_optimizer_default_settings/fixtures/set_resize_filter/nearest.yaml index cc244858f..51075c4f5 100644 --- a/fastly/fixtures/image_optimizer_default_settings/set_resize_filter/nearest.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/set_resize_filter/nearest.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"nearest","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:33 GMT + - Sat, 07 Dec 2024 16:56:48 GMT Fastly-Ratelimit-Remaining: - - "991" + - "977" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703393.733035,VS0,VE271 + - S1733590608.127708,VS0,VE250 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/update_1_get.yaml b/fastly/image_optimizer_default_settings/fixtures/update_1_get.yaml similarity index 69% rename from fastly/fixtures/image_optimizer_default_settings/update_1_get.yaml rename to fastly/image_optimizer_default_settings/fixtures/update_1_get.yaml index 9bc24da00..3d6a5aaac 100644 --- a/fastly/fixtures/image_optimizer_default_settings/update_1_get.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/update_1_get.yaml @@ -6,8 +6,8 @@ interactions: form: {} headers: User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: GET response: body: '{"resize_filter":"lanczos3","webp":false,"webp_quality":20,"jpeg_type":"auto","jpeg_quality":85,"upscale":false,"allow_video":false}' @@ -19,11 +19,11 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:30 GMT + - Sat, 07 Dec 2024 16:56:46 GMT Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -31,15 +31,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703390.390128,VS0,VE177 + - S1733590606.078044,VS0,VE134 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/update_1_patch.yaml b/fastly/image_optimizer_default_settings/fixtures/update_1_patch.yaml similarity index 72% rename from fastly/fixtures/image_optimizer_default_settings/update_1_patch.yaml rename to fastly/image_optimizer_default_settings/fixtures/update_1_patch.yaml index 945a87614..9b6750eb3 100644 --- a/fastly/fixtures/image_optimizer_default_settings/update_1_patch.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/update_1_patch.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"lanczos3","webp":false,"webp_quality":20,"jpeg_type":"auto","jpeg_quality":85,"upscale":false,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:30 GMT + - Sat, 07 Dec 2024 16:56:46 GMT Fastly-Ratelimit-Remaining: - - "998" + - "984" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703390.918211,VS0,VE458 + - S1733590606.788850,VS0,VE278 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/update_2_get.yaml b/fastly/image_optimizer_default_settings/fixtures/update_2_get.yaml similarity index 69% rename from fastly/fixtures/image_optimizer_default_settings/update_2_get.yaml rename to fastly/image_optimizer_default_settings/fixtures/update_2_get.yaml index b5f4dd2b6..1c891ec87 100644 --- a/fastly/fixtures/image_optimizer_default_settings/update_2_get.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/update_2_get.yaml @@ -6,8 +6,8 @@ interactions: form: {} headers: User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: GET response: body: '{"resize_filter":"lanczos3","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -19,11 +19,11 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:31 GMT + - Sat, 07 Dec 2024 16:56:46 GMT Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -31,15 +31,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703391.910192,VS0,VE249 + - S1733590607.592335,VS0,VE114 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/update_2_patch.yaml b/fastly/image_optimizer_default_settings/fixtures/update_2_patch.yaml similarity index 72% rename from fastly/fixtures/image_optimizer_default_settings/update_2_patch.yaml rename to fastly/image_optimizer_default_settings/fixtures/update_2_patch.yaml index 0962406be..8ad292d38 100644 --- a/fastly/fixtures/image_optimizer_default_settings/update_2_patch.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/update_2_patch.yaml @@ -10,8 +10,8 @@ interactions: Content-Type: - application/json User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/87/image_optimizer_default_settings + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version/6/image_optimizer_default_settings method: PATCH response: body: '{"resize_filter":"lanczos3","webp":true,"webp_quality":42,"jpeg_type":"auto","jpeg_quality":85,"upscale":true,"allow_video":false}' @@ -23,15 +23,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:30 GMT + - Sat, 07 Dec 2024 16:56:46 GMT Fastly-Ratelimit-Remaining: - - "997" + - "983" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -39,15 +39,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100033-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703391.584378,VS0,VE312 + - S1733590606.220593,VS0,VE267 status: 200 OK code: 200 duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/version.yaml b/fastly/image_optimizer_default_settings/fixtures/version.yaml similarity index 65% rename from fastly/fixtures/image_optimizer_default_settings/version.yaml rename to fastly/image_optimizer_default_settings/fixtures/version.yaml index 0846c113c..67334dabe 100644 --- a/fastly/fixtures/image_optimizer_default_settings/version.yaml +++ b/fastly/image_optimizer_default_settings/fixtures/version.yaml @@ -8,11 +8,11 @@ interactions: Content-Type: - application/x-www-form-urlencoded User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) url: https://api.fastly.com/service/kKJb5bOFI47uHeBVluGfX1/version method: POST response: - body: '{"service_id":"kKJb5bOFI47uHeBVluGfX1","number":87}' + body: '{"service_id":"kKJb5bOFI47uHeBVluGfX1","number":6}' headers: Accept-Ranges: - bytes @@ -21,15 +21,15 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:27 GMT + - Sat, 07 Dec 2024 16:56:44 GMT Fastly-Ratelimit-Remaining: - - "999" + - "985" Fastly-Ratelimit-Reset: - - "1715706000" + - "1733590800" Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 200 OK Strict-Transport-Security: @@ -37,15 +37,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-kigq8000132-CHI, cache-nyc-kteb1890026-NYC X-Timer: - - S1715703387.397400,VS0,VE452 + - S1733590605.651690,VS0,VE258 status: 200 OK code: 200 duration: "" diff --git a/fastly/image_optimizer_default_settings_test.go b/fastly/image_optimizer_default_settings/image_optimizer_default_settings_test.go similarity index 54% rename from fastly/image_optimizer_default_settings_test.go rename to fastly/image_optimizer_default_settings/image_optimizer_default_settings_test.go index 2719d600a..68185e915 100644 --- a/fastly/image_optimizer_default_settings_test.go +++ b/fastly/image_optimizer_default_settings/image_optimizer_default_settings_test.go @@ -1,8 +1,11 @@ -package fastly +package image_optimizer_default_settings_test import ( "strings" "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products/image_optimizer" ) // TestClient_ImageOptimizerDefaultSettings tests the Image Optimizer Default Settings API @@ -12,18 +15,15 @@ import ( func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { t.Parallel() - fixtureBase := "image_optimizer_default_settings/" + fixtureBase := "" - testVersion := CreateTestVersion(t, fixtureBase+"version", TestDeliveryServiceID) + testVersion := fastly.CreateTestVersion(t, fixtureBase+"version", fastly.TestDeliveryServiceID) var err error // Enable IO - Record(t, fixtureBase+"enable_product", func(c *Client) { - _, err = c.EnableProduct(&ProductEnablementInput{ - ProductID: ProductImageOptimizer, - ServiceID: TestDeliveryServiceID, - }) + fastly.Record(t, fixtureBase+"enable_product", func(c *fastly.Client) { + _, err = image_optimizer.Enable(c, fastly.TestDeliveryServiceID) }) if err != nil { t.Fatal(err) @@ -31,24 +31,21 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { // Ensure we disable IO on the service after the test defer func() { - Record(t, fixtureBase+"disable_product", func(c *Client) { - err = c.DisableProduct(&ProductEnablementInput{ - ProductID: ProductImageOptimizer, - ServiceID: TestDeliveryServiceID, - }) - }) + fastly.Record(t, fixtureBase+"disable_product", func(c *fastly.Client) { + _, err = image_optimizer.Enable(c, fastly.TestDeliveryServiceID) - if err != nil { - t.Fatal(err) - } + if err != nil { + t.Fatal(err) + } + }) }() - var defaultSettings *ImageOptimizerDefaultSettings + var defaultSettings *fastly.ImageOptimizerDefaultSettings // Fetch - Record(t, fixtureBase+"original_fetch", func(c *Client) { - defaultSettings, err = c.GetImageOptimizerDefaultSettings(&GetImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"original_fetch", func(c *fastly.Client) { + defaultSettings, err = c.GetImageOptimizerDefaultSettings(&fastly.GetImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, }) }) @@ -60,17 +57,17 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { // Reset our settings back to the original defer func() { - Record(t, fixtureBase+"final_reset", func(c *Client) { + fastly.Record(t, fixtureBase+"final_reset", func(c *fastly.Client) { if originalSettings != nil { - _, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + _, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, // just use default resizefilter & jpegtype since it doesn't matter much, and it's annoying // to parse the API output strings back into enums. - ResizeFilter: ToPointer(ImageOptimizerNearest), + ResizeFilter: fastly.ToPointer(fastly.ImageOptimizerNearest), Webp: &originalSettings.Webp, WebpQuality: &originalSettings.WebpQuality, - JpegType: ToPointer(ImageOptimizerAuto), + JpegType: fastly.ToPointer(fastly.ImageOptimizerAuto), JpegQuality: &originalSettings.JpegQuality, Upscale: &originalSettings.Upscale, AllowVideo: &originalSettings.AllowVideo, @@ -87,9 +84,9 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { newUpscale := false // Change some stuff - Record(t, fixtureBase+"update_1_patch", func(c *Client) { - defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"update_1_patch", func(c *fastly.Client) { + defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, Webp: &newWebp, WebpQuality: &newWebpQuality, @@ -111,9 +108,9 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { } // Confirm our changes were applied permanently - Record(t, fixtureBase+"update_1_get", func(c *Client) { - defaultSettings, err = c.GetImageOptimizerDefaultSettings(&GetImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"update_1_get", func(c *fastly.Client) { + defaultSettings, err = c.GetImageOptimizerDefaultSettings(&fastly.GetImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, }) }) @@ -136,9 +133,9 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { newWebpQuality = 42 newUpscale = true - Record(t, fixtureBase+"update_2_patch", func(c *Client) { - defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"update_2_patch", func(c *fastly.Client) { + defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, Webp: &newWebp, WebpQuality: &newWebpQuality, @@ -160,9 +157,9 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { } // Confirm our changes were applied permanently (again) - Record(t, fixtureBase+"update_2_get", func(c *Client) { - defaultSettings, err = c.GetImageOptimizerDefaultSettings(&GetImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"update_2_get", func(c *fastly.Client) { + defaultSettings, err = c.GetImageOptimizerDefaultSettings(&fastly.GetImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, }) }) @@ -183,9 +180,9 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { // Apply a setting that produces a server-side error, and confirm it's handled well. newWebpQuality = 105 - Record(t, fixtureBase+"incorrect_fetch", func(c *Client) { - _, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"incorrect_fetch", func(c *fastly.Client) { + _, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, WebpQuality: &newWebpQuality, }) @@ -199,10 +196,10 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { } // Confirm all resize_filter & jpeg_type values are accepted - for _, resizeFilter := range []ImageOptimizerResizeFilter{ImageOptimizerLanczos3, ImageOptimizerLanczos2, ImageOptimizerBicubic, ImageOptimizerBilinear, ImageOptimizerNearest} { - Record(t, fixtureBase+"set_resize_filter/"+resizeFilter.String(), func(c *Client) { - defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + for _, resizeFilter := range []fastly.ImageOptimizerResizeFilter{fastly.ImageOptimizerLanczos3, fastly.ImageOptimizerLanczos2, fastly.ImageOptimizerBicubic, fastly.ImageOptimizerBilinear, fastly.ImageOptimizerNearest} { + fastly.Record(t, fixtureBase+"set_resize_filter/"+resizeFilter.String(), func(c *fastly.Client) { + defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, ResizeFilter: &resizeFilter, }) @@ -212,10 +209,10 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { } } - for _, jpegType := range []ImageOptimizerJpegType{ImageOptimizerAuto, ImageOptimizerBaseline, ImageOptimizerProgressive} { - Record(t, fixtureBase+"set_jpeg_type/"+jpegType.String(), func(c *Client) { - defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + for _, jpegType := range []fastly.ImageOptimizerJpegType{fastly.ImageOptimizerAuto, fastly.ImageOptimizerBaseline, fastly.ImageOptimizerProgressive} { + fastly.Record(t, fixtureBase+"set_jpeg_type/"+jpegType.String(), func(c *fastly.Client) { + defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, JpegType: &jpegType, }) @@ -226,37 +223,37 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) { } // Confirm a full request is accepted - that all parameters in our library match the API's expectations - Record(t, fixtureBase+"set_full", func(c *Client) { - defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ - ServiceID: TestDeliveryServiceID, + fastly.Record(t, fixtureBase+"set_full", func(c *fastly.Client) { + defaultSettings, err = c.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: fastly.TestDeliveryServiceID, ServiceVersion: *testVersion.Number, - ResizeFilter: ToPointer(ImageOptimizerLanczos3), - Webp: ToPointer(false), - WebpQuality: ToPointer(85), - JpegType: ToPointer(ImageOptimizerAuto), - JpegQuality: ToPointer(85), - Upscale: ToPointer(false), - AllowVideo: ToPointer(false), + ResizeFilter: fastly.ToPointer(fastly.ImageOptimizerLanczos3), + Webp: fastly.ToPointer(false), + WebpQuality: fastly.ToPointer(85), + JpegType: fastly.ToPointer(fastly.ImageOptimizerAuto), + JpegQuality: fastly.ToPointer(85), + Upscale: fastly.ToPointer(false), + AllowVideo: fastly.ToPointer(false), }) }) } func TestClient_GetImageOptimizerDefaultSettings_validation(t *testing.T) { var err error - _, err = TestClient.GetImageOptimizerDefaultSettings(&GetImageOptimizerDefaultSettingsInput{ + _, err = fastly.TestClient.GetImageOptimizerDefaultSettings(&fastly.GetImageOptimizerDefaultSettingsInput{ ServiceID: "", ServiceVersion: 3, }) - if err != ErrMissingServiceID { - t.Errorf("expected error %v; got: %v", ErrMissingServiceID, err) + if err != fastly.ErrMissingServiceID { + t.Errorf("expected error %v; got: %v", fastly.ErrMissingServiceID, err) } - _, err = TestClient.GetImageOptimizerDefaultSettings(&GetImageOptimizerDefaultSettingsInput{ + _, err = fastly.TestClient.GetImageOptimizerDefaultSettings(&fastly.GetImageOptimizerDefaultSettingsInput{ ServiceID: "foo", ServiceVersion: 0, }) - if err != ErrMissingServiceVersion { - t.Errorf("expected error %v; got: %v", ErrMissingServiceVersion, err) + if err != fastly.ErrMissingServiceVersion { + t.Errorf("expected error %v; got: %v", fastly.ErrMissingServiceVersion, err) } } @@ -264,29 +261,29 @@ func TestClient_UpdateImageOptimizerDefaultSettings_validation(t *testing.T) { newUpscale := true var err error - _, err = TestClient.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ + _, err = fastly.TestClient.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ ServiceID: "", ServiceVersion: 3, Upscale: &newUpscale, }) - if err != ErrMissingServiceID { - t.Errorf("expected error %v; got: %v", ErrMissingServiceID, err) + if err != fastly.ErrMissingServiceID { + t.Errorf("expected error %v; got: %v", fastly.ErrMissingServiceID, err) } - _, err = TestClient.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ + _, err = fastly.TestClient.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ ServiceID: "foo", ServiceVersion: 0, Upscale: &newUpscale, }) - if err != ErrMissingServiceVersion { - t.Errorf("expected error %v; got: %v", ErrMissingServiceVersion, err) + if err != fastly.ErrMissingServiceVersion { + t.Errorf("expected error %v; got: %v", fastly.ErrMissingServiceVersion, err) } - _, err = TestClient.UpdateImageOptimizerDefaultSettings(&UpdateImageOptimizerDefaultSettingsInput{ + _, err = fastly.TestClient.UpdateImageOptimizerDefaultSettings(&fastly.UpdateImageOptimizerDefaultSettingsInput{ ServiceID: "foo", ServiceVersion: 3, }) - if err != ErrMissingImageOptimizerDefaultSetting { - t.Errorf("expected error: %v, got: %v", ErrMissingImageOptimizerDefaultSetting, err) + if err != fastly.ErrMissingImageOptimizerDefaultSetting { + t.Errorf("expected error: %v, got: %v", fastly.ErrMissingImageOptimizerDefaultSetting, err) } } diff --git a/fastly/product_enablement.go b/fastly/product_enablement.go index 51c4188a2..913b48635 100644 --- a/fastly/product_enablement.go +++ b/fastly/product_enablement.go @@ -59,6 +59,9 @@ type ProductEnablementInput struct { } // GetProduct retrieves the details of the product enabled on the service. +// +// Deprecated: The 'Get' functions in the product-specific packages +// should be used instead of this function. func (c *Client) GetProduct(i *ProductEnablementInput) (*ProductEnablement, error) { if i.ProductID == ProductUndefined { return nil, ErrMissingProductID @@ -84,6 +87,9 @@ func (c *Client) GetProduct(i *ProductEnablementInput) (*ProductEnablement, erro } // EnableProduct enables the specified product on the service. +// +// Deprecated: The 'Enable' functions in the product-specific packages +// should be used instead of this function. func (c *Client) EnableProduct(i *ProductEnablementInput) (*ProductEnablement, error) { if i.ProductID == ProductUndefined { return nil, ErrMissingProductID @@ -108,6 +114,9 @@ func (c *Client) EnableProduct(i *ProductEnablementInput) (*ProductEnablement, e } // DisableProduct disables the specified product on the service. +// +// Deprecated: The 'Disable' functions in the product-specific packages +// should be used instead of this function. func (c *Client) DisableProduct(i *ProductEnablementInput) error { if i.ProductID == ProductUndefined { return ErrMissingProductID diff --git a/fastly/products/api_output.go b/fastly/products/api_output.go new file mode 100644 index 000000000..d8c462665 --- /dev/null +++ b/fastly/products/api_output.go @@ -0,0 +1,38 @@ +package products + +// EnableOutput represents an enablement response from the Fastly +// API. Some products will use this structure directly, others will +// embed it into their own structure. +type EnableOutput struct { + Product *enableOutputNested `mapstructure:"product"` + Service *enableOutputNested `mapstructure:"service"` +} + +type enableOutputNested struct { + Object *string `mapstructure:"object,omitempty"` + ID *string `mapstructure:"id,omitempty"` +} + +// GetProductID return the ProductID inside an EnableOutput structure. +// +// This method is required, even though the field in the structure is +// exported, because there is an interface in an internal package +// which expects 'output' types to provide this method. +func (o *EnableOutput) ProductID() *string { + return o.Product.ID +} + +// GetServiceID return the ServiceID inside an EnableOutput structure. +// +// This method is required, even though the field in the structure is +// exported, because there is an interface in an internal package +// which expects 'output' types to provide this method. +func (o *EnableOutput) ServiceID() *string { + return o.Service.ID +} + +// ConfigureOutput represents a configuration response from the Fastly +// API. Products will embed this into their own structure. +type ConfigureOutput struct { + EnableOutput `mapstructure:",squash"` +} diff --git a/fastly/products/bot_management/api.go b/fastly/products/bot_management/api.go new file mode 100644 index 000000000..d4b4e260e --- /dev/null +++ b/fastly/products/bot_management/api.go @@ -0,0 +1,36 @@ +package bot_management + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "bot_management" + +// Get gets the status of the Bot Management product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Bot Management product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Bot Management product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/bot_management/api_test.go b/fastly/products/bot_management/api_test.go new file mode 100644 index 000000000..2222f22e6 --- /dev/null +++ b/fastly/products/bot_management/api_test.go @@ -0,0 +1,55 @@ +package bot_management_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/bot_management" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: bot_management.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: bot_management.Enable, + ProductID: bot_management.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: bot_management.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/bot_management/doc.go b/fastly/products/bot_management/doc.go new file mode 100644 index 000000000..a371577fc --- /dev/null +++ b/fastly/products/bot_management/doc.go @@ -0,0 +1,3 @@ +// Package bot_management contains API operations to enable and +// disable the Bot Management product on a service +package bot_management diff --git a/fastly/products/bot_management/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/bot_management/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..5e417583b --- /dev/null +++ b/fastly/products/bot_management/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000078-CHI, cache-nyc-kteb1890085-NYC + X-Timer: + - S1733771529.589696,VS0,VE113 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/bot_management/fixtures/disable.yaml b/fastly/products/bot_management/fixtures/disable.yaml new file mode 100644 index 000000000..550133f9c --- /dev/null +++ b/fastly/products/bot_management/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:07 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100042-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591105.463304,VS0,VE1865 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/bot_management/fixtures/enable.yaml b/fastly/products/bot_management/fixtures/enable.yaml new file mode 100644 index 000000000..8af689ad0 --- /dev/null +++ b/fastly/products/bot_management/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"bot_management","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "204" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100042-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.163627,VS0,VE1199 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/bot_management/fixtures/get-after-disablement.yaml b/fastly/products/bot_management/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..2750256f7 --- /dev/null +++ b/fastly/products/bot_management/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:07 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100042-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591107.336996,VS0,VE115 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/bot_management/fixtures/get-after-enablement.yaml b/fastly/products/bot_management/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..bf30b86e8 --- /dev/null +++ b/fastly/products/bot_management/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"bot_management","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "204" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100042-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591105.372442,VS0,VE80 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/bot_management/fixtures/get-before-enablement.yaml b/fastly/products/bot_management/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..c6702d51d --- /dev/null +++ b/fastly/products/bot_management/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/bot_management/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100042-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.019632,VS0,VE127 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/brotli_compression/api.go b/fastly/products/brotli_compression/api.go new file mode 100644 index 000000000..e0f3be96f --- /dev/null +++ b/fastly/products/brotli_compression/api.go @@ -0,0 +1,36 @@ +package brotli_compression + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "brotli_compression" + +// Get gets the status of the Brotli Compression product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Brotli Compression product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Brotli Compression product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/brotli_compression/api_test.go b/fastly/products/brotli_compression/api_test.go new file mode 100644 index 000000000..1b7925bd6 --- /dev/null +++ b/fastly/products/brotli_compression/api_test.go @@ -0,0 +1,55 @@ +package brotli_compression_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/brotli_compression" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: brotli_compression.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: brotli_compression.Enable, + ProductID: brotli_compression.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: brotli_compression.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/brotli_compression/doc.go b/fastly/products/brotli_compression/doc.go new file mode 100644 index 000000000..b25d7d1f0 --- /dev/null +++ b/fastly/products/brotli_compression/doc.go @@ -0,0 +1,3 @@ +// Package brotli_compression contains API operations to enable and +// disable the Brotli Compression product on a service +package brotli_compression diff --git a/fastly/products/brotli_compression/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/brotli_compression/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..35259708e --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100170-CHI, cache-nyc-kteb1890030-NYC + X-Timer: + - S1733771529.600389,VS0,VE104 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/brotli_compression/fixtures/disable.yaml b/fastly/products/brotli_compression/fixtures/disable.yaml new file mode 100644 index 000000000..90bcafc6b --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000053-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.468398,VS0,VE175 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/brotli_compression/fixtures/enable.yaml b/fastly/products/brotli_compression/fixtures/enable.yaml new file mode 100644 index 000000000..b5ca458fa --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"brotli_compression","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "212" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000053-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.159263,VS0,VE214 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/brotli_compression/fixtures/get-after-disablement.yaml b/fastly/products/brotli_compression/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..bac8bd007 --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000053-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591105.655445,VS0,VE129 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/brotli_compression/fixtures/get-after-enablement.yaml b/fastly/products/brotli_compression/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..86cae124c --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"brotli_compression","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "212" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000053-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.382753,VS0,VE69 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/brotli_compression/fixtures/get-before-enablement.yaml b/fastly/products/brotli_compression/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..f9a2151cf --- /dev/null +++ b/fastly/products/brotli_compression/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/brotli_compression/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000053-CHI, cache-ewr-kewr1740076-EWR + X-Timer: + - S1733591104.019987,VS0,VE126 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ddos_protection/api.go b/fastly/products/ddos_protection/api.go new file mode 100644 index 000000000..b4ddb8a71 --- /dev/null +++ b/fastly/products/ddos_protection/api.go @@ -0,0 +1,79 @@ +package ddos_protection + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "ddos_protection" + +// ErrMissingMode is the error returned by the UpdateConfiguration +// function when it is passed a ConfigureInput struct with a mode +// field that is empty. +var ErrMissingMode = fastly.NewFieldError("Mode") + +type ConfigureInput struct { + Mode string `json:"mode"` +} + +type ConfigureOutput struct { + products.ConfigureOutput `mapstructure:",squash"` + Configuration *configureOutputNested `mapstructure:"configuration"` +} + +type configureOutputNested struct { + Mode *string `mapstructure:"mode"` +} + +// Get gets the status of the DDoS Protection product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the DDoS Protection product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the DDoS Protection product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// GetConfiguration gets the configuration of the DDoS Protection product on the service. +func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, error) { + return productcore.Get[*ConfigureOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + URLComponents: []string{"configuration"}, + }) +} + +// UpdateConfiguration updates the configuration of the DDoS Protection product on the service. +func UpdateConfiguration(c *fastly.Client, serviceID string, i *ConfigureInput) (*ConfigureOutput, error) { + if i.Mode == "" { + return nil, ErrMissingMode + } + + return productcore.Patch[*ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + URLComponents: []string{"configuration"}, + Input: i, + }) +} diff --git a/fastly/products/ddos_protection/api_test.go b/fastly/products/ddos_protection/api_test.go new file mode 100644 index 000000000..0cc433dbf --- /dev/null +++ b/fastly/products/ddos_protection/api_test.go @@ -0,0 +1,95 @@ +package ddos_protection_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/ddos_protection" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" + + "github.com/stretchr/testify/require" +) + +var serviceID = fastly.TestDeliveryServiceID + +func TestUpdateConfigurationMissingMode(t *testing.T) { + t.Parallel() + + _, err := ddos_protection.UpdateConfiguration(nil, serviceID, &ddos_protection.ConfigureInput{Mode: ""}) + + require.ErrorIs(t, err, ddos_protection.ErrMissingMode) +} + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: ddos_protection.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: ddos_protection.Enable, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ddos_protection.ConfigureOutput]{ + Phase: "default", + OpFn: ddos_protection.GetConfiguration, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, o *ddos_protection.ConfigureOutput) { + require.NotNilf(t, o.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "log", *o.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ddos_protection.ConfigureOutput, *ddos_protection.ConfigureInput]{ + OpFn: ddos_protection.UpdateConfiguration, + Input: &ddos_protection.ConfigureInput{Mode: "block"}, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, o *ddos_protection.ConfigureOutput) { + require.NotNilf(t, o.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "block", *o.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ddos_protection.ConfigureOutput]{ + Phase: "after update", + OpFn: ddos_protection.GetConfiguration, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, o *ddos_protection.ConfigureOutput) { + require.NotNilf(t, o.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "block", *o.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: ddos_protection.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablementAndConfiguration(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/ddos_protection/doc.go b/fastly/products/ddos_protection/doc.go new file mode 100644 index 000000000..e53350823 --- /dev/null +++ b/fastly/products/ddos_protection/doc.go @@ -0,0 +1,3 @@ +// Package ddos_protection contains API operations to enable, disable, +// and configure the DDoS Protection product on a service +package ddos_protection diff --git a/fastly/products/ddos_protection/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/ddos_protection/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..3d87c3fb9 --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-nyc-kteb1890043-NYC + X-Timer: + - S1733771529.616251,VS0,VE93 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/disable.yaml b/fastly/products/ddos_protection/fixtures/disable.yaml new file mode 100644 index 000000000..850e9612b --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681765.450297,VS0,VE447 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/enable.yaml b/fastly/products/ddos_protection/fixtures/enable.yaml new file mode 100644 index 000000000..90da7e16e --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"ddos_protection","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "206" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681764.513522,VS0,VE906 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/get-after-disablement.yaml b/fastly/products/ddos_protection/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..2433a8d7c --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681766.904812,VS0,VE118 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/get-after-enablement.yaml b/fastly/products/ddos_protection/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..8f5e2923b --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"ddos_protection","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "206" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681764.427404,VS0,VE122 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/get-before-enablement.yaml b/fastly/products/ddos_protection/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..bd66d614c --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:03 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100026-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681763.444519,VS0,VE56 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/get-configuration-after-update.yaml b/fastly/products/ddos_protection/fixtures/get-configuration-after-update.yaml new file mode 100644 index 000000000..270bacaa2 --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/get-configuration-after-update.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: GET + response: + body: | + {"product":{"id":"ddos_protection","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"mode":"block"},"_links":{"self":"/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "253" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000034-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681765.318816,VS0,VE125 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/get-configuration-default.yaml b/fastly/products/ddos_protection/fixtures/get-configuration-default.yaml new file mode 100644 index 000000000..512e4b83a --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/get-configuration-default.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: GET + response: + body: | + {"product":{"id":"ddos_protection","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"mode":"log"},"_links":{"self":"/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "251" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000034-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681765.559731,VS0,VE120 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ddos_protection/fixtures/update-configuration.yaml b/fastly/products/ddos_protection/fixtures/update-configuration.yaml new file mode 100644 index 000000000..ef702b16a --- /dev/null +++ b/fastly/products/ddos_protection/fixtures/update-configuration.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: '{"mode":"block"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: PATCH + response: + body: | + {"product":{"id":"ddos_protection","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"mode":"block"},"_links":{"self":"/enabled-products/v1/ddos_protection/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "253" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000034-CHI, cache-ewr-kewr1740025-EWR + X-Timer: + - S1733681765.780624,VS0,VE531 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/doc.go b/fastly/products/doc.go new file mode 100644 index 000000000..d7b2aa76d --- /dev/null +++ b/fastly/products/doc.go @@ -0,0 +1,4 @@ +// Package products contains subpackages which offer various +// operations to enable, disable, and configure Fastly products on a +// service +package products diff --git a/fastly/products/domain_inspector/api.go b/fastly/products/domain_inspector/api.go new file mode 100644 index 000000000..cbe9659e6 --- /dev/null +++ b/fastly/products/domain_inspector/api.go @@ -0,0 +1,36 @@ +package domain_inspector + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "domain_inspector" + +// Get gets the status of the Domain Inspector product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Domain Inspector product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Domain Inspector product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/domain_inspector/api_test.go b/fastly/products/domain_inspector/api_test.go new file mode 100644 index 000000000..fe426ae79 --- /dev/null +++ b/fastly/products/domain_inspector/api_test.go @@ -0,0 +1,55 @@ +package domain_inspector_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/domain_inspector" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: domain_inspector.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: domain_inspector.Enable, + ProductID: domain_inspector.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: domain_inspector.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/domain_inspector/doc.go b/fastly/products/domain_inspector/doc.go new file mode 100644 index 000000000..6e5a20d44 --- /dev/null +++ b/fastly/products/domain_inspector/doc.go @@ -0,0 +1,3 @@ +// Package domain_inspector contains API operations to enable and +// disable the Domain Inspector product on a service +package domain_inspector diff --git a/fastly/products/domain_inspector/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/domain_inspector/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..d835b9be2 --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100140-CHI, cache-nyc-kteb1890059-NYC + X-Timer: + - S1733771529.937519,VS0,VE49 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/domain_inspector/fixtures/disable.yaml b/fastly/products/domain_inspector/fixtures/disable.yaml new file mode 100644 index 000000000..895f74820 --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100151-CHI, cache-ewr-kewr1740037-EWR + X-Timer: + - S1733591105.090050,VS0,VE830 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/domain_inspector/fixtures/enable.yaml b/fastly/products/domain_inspector/fixtures/enable.yaml new file mode 100644 index 000000000..6bd1f2520 --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"domain_inspector","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "208" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100151-CHI, cache-ewr-kewr1740037-EWR + X-Timer: + - S1733591104.158944,VS0,VE828 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/domain_inspector/fixtures/get-after-disablement.yaml b/fastly/products/domain_inspector/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..21ea863cd --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100151-CHI, cache-ewr-kewr1740037-EWR + X-Timer: + - S1733591106.930305,VS0,VE120 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/domain_inspector/fixtures/get-after-enablement.yaml b/fastly/products/domain_inspector/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..3ac05a335 --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"domain_inspector","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "208" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100151-CHI, cache-ewr-kewr1740037-EWR + X-Timer: + - S1733591105.995257,VS0,VE85 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/domain_inspector/fixtures/get-before-enablement.yaml b/fastly/products/domain_inspector/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..4a0a621ac --- /dev/null +++ b/fastly/products/domain_inspector/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/domain_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100151-CHI, cache-ewr-kewr1740037-EWR + X-Timer: + - S1733591104.014854,VS0,VE133 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/fanout/api.go b/fastly/products/fanout/api.go new file mode 100644 index 000000000..39548ec9d --- /dev/null +++ b/fastly/products/fanout/api.go @@ -0,0 +1,36 @@ +package fanout + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "fanout" + +// Get gets the status of the Fanout product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Fanout product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Fanout product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/fanout/api_test.go b/fastly/products/fanout/api_test.go new file mode 100644 index 000000000..177c7b279 --- /dev/null +++ b/fastly/products/fanout/api_test.go @@ -0,0 +1,55 @@ +package fanout_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/fanout" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestComputeServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: fanout.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: fanout.Get, + ProductID: fanout.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: fanout.Enable, + ProductID: fanout.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: fanout.Get, + ProductID: fanout.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: fanout.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: fanout.Get, + ProductID: fanout.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/fanout/doc.go b/fastly/products/fanout/doc.go new file mode 100644 index 000000000..0d407329a --- /dev/null +++ b/fastly/products/fanout/doc.go @@ -0,0 +1,3 @@ +// Package fanout contains API operations to enable and +// disable the Fanout product on a service +package fanout diff --git a/fastly/products/fanout/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/fanout/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..7d3597cac --- /dev/null +++ b/fastly/products/fanout/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-nyc-kteb1890093-NYC + X-Timer: + - S1733771529.253698,VS0,VE48 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/fanout/fixtures/disable.yaml b/fastly/products/fanout/fixtures/disable.yaml new file mode 100644 index 000000000..b27bce6fe --- /dev/null +++ b/fastly/products/fanout/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100071-CHI, cache-ewr-kewr1740073-EWR + X-Timer: + - S1733591105.148733,VS0,VE415 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/fanout/fixtures/enable.yaml b/fastly/products/fanout/fixtures/enable.yaml new file mode 100644 index 000000000..05357a244 --- /dev/null +++ b/fastly/products/fanout/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: PUT + response: + body: | + {"product":{"id":"fanout","object":"product"},"service":{"id":"XsjdElScZGjmfCcTwsYRC1","object":"service"},"_links":{"self":"/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "188" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100071-CHI, cache-ewr-kewr1740073-EWR + X-Timer: + - S1733591104.084375,VS0,VE932 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/fanout/fixtures/get-after-disablement.yaml b/fastly/products/fanout/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..785aafc75 --- /dev/null +++ b/fastly/products/fanout/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100071-CHI, cache-ewr-kewr1740073-EWR + X-Timer: + - S1733591106.575511,VS0,VE113 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/fanout/fixtures/get-after-enablement.yaml b/fastly/products/fanout/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..54243c444 --- /dev/null +++ b/fastly/products/fanout/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: GET + response: + body: | + {"product":{"id":"fanout","object":"product"},"service":{"id":"XsjdElScZGjmfCcTwsYRC1","object":"service"},"_links":{"self":"/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "188" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100071-CHI, cache-ewr-kewr1740073-EWR + X-Timer: + - S1733591105.026541,VS0,VE112 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/fanout/fixtures/get-before-enablement.yaml b/fastly/products/fanout/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..c3628eac4 --- /dev/null +++ b/fastly/products/fanout/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/fanout/services/XsjdElScZGjmfCcTwsYRC1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100071-CHI, cache-ewr-kewr1740073-EWR + X-Timer: + - S1733591104.020503,VS0,VE53 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/image_optimizer/api.go b/fastly/products/image_optimizer/api.go new file mode 100644 index 000000000..d808c8af3 --- /dev/null +++ b/fastly/products/image_optimizer/api.go @@ -0,0 +1,36 @@ +package image_optimizer + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "image_optimizer" + +// Get gets the status of the Image Optimizer product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Image Optimizer product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Image Optimizer product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/image_optimizer/api_test.go b/fastly/products/image_optimizer/api_test.go new file mode 100644 index 000000000..20535913e --- /dev/null +++ b/fastly/products/image_optimizer/api_test.go @@ -0,0 +1,55 @@ +package image_optimizer_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/image_optimizer" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: image_optimizer.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: image_optimizer.Enable, + ProductID: image_optimizer.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: image_optimizer.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/image_optimizer/doc.go b/fastly/products/image_optimizer/doc.go new file mode 100644 index 000000000..bad0f4a7b --- /dev/null +++ b/fastly/products/image_optimizer/doc.go @@ -0,0 +1,3 @@ +// Package image_optimizer contains API operations to enable and +// disable the Image Optimizer product on a service +package image_optimizer diff --git a/fastly/products/image_optimizer/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/image_optimizer/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..5b8c7965b --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000109-CHI, cache-nyc-kteb1890059-NYC + X-Timer: + - S1733771529.374023,VS0,VE80 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/image_optimizer/fixtures/disable.yaml b/fastly/products/image_optimizer/fixtures/disable.yaml new file mode 100644 index 000000000..f809c9ada --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-ewr-kewr1740044-EWR + X-Timer: + - S1733591106.788475,VS0,VE1135 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/image_optimizer/fixtures/enable.yaml b/fastly/products/image_optimizer/fixtures/enable.yaml new file mode 100644 index 000000000..2701bd411 --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"image_optimizer","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "206" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-ewr-kewr1740044-EWR + X-Timer: + - S1733591104.467864,VS0,VE1186 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/image_optimizer/fixtures/get-after-disablement.yaml b/fastly/products/image_optimizer/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..c0c3cf3e1 --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:07 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-ewr-kewr1740044-EWR + X-Timer: + - S1733591107.931923,VS0,VE90 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/image_optimizer/fixtures/get-after-enablement.yaml b/fastly/products/image_optimizer/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..56571567e --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"image_optimizer","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "206" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-ewr-kewr1740044-EWR + X-Timer: + - S1733591106.665992,VS0,VE116 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/image_optimizer/fixtures/get-before-enablement.yaml b/fastly/products/image_optimizer/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..86f562193 --- /dev/null +++ b/fastly/products/image_optimizer/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100132-CHI, cache-ewr-kewr1740044-EWR + X-Timer: + - S1733591104.339829,VS0,VE113 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/log_explorer_insights/api.go b/fastly/products/log_explorer_insights/api.go new file mode 100644 index 000000000..82b1dfbaa --- /dev/null +++ b/fastly/products/log_explorer_insights/api.go @@ -0,0 +1,36 @@ +package log_explorer_insights + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "log_explorer_insights" + +// Get gets the status of the Log Explorer Bot Management Insights product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Log Explorer Bot Management Insights product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Log Explorer Bot Management Insights product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/log_explorer_insights/api_test.go b/fastly/products/log_explorer_insights/api_test.go new file mode 100644 index 000000000..2657faefa --- /dev/null +++ b/fastly/products/log_explorer_insights/api_test.go @@ -0,0 +1,55 @@ +package log_explorer_insights_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/log_explorer_insights" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: log_explorer_insights.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: log_explorer_insights.Enable, + ProductID: log_explorer_insights.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: log_explorer_insights.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/log_explorer_insights/doc.go b/fastly/products/log_explorer_insights/doc.go new file mode 100644 index 000000000..714d19bb2 --- /dev/null +++ b/fastly/products/log_explorer_insights/doc.go @@ -0,0 +1,3 @@ +// Package log_explorer_insights contains API operations to enable and +// disable the Log Explorer & Insights product on a service +package log_explorer_insights diff --git a/fastly/products/log_explorer_insights/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/log_explorer_insights/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..ff0be8c31 --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-nyc-kteb1890040-NYC + X-Timer: + - S1733771530.584288,VS0,VE80 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/log_explorer_insights/fixtures/disable.yaml b/fastly/products/log_explorer_insights/fixtures/disable.yaml new file mode 100644 index 000000000..ccdbfc134 --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-ewr-kewr1740047-EWR + X-Timer: + - S1733591107.837503,VS0,VE1804 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/log_explorer_insights/fixtures/enable.yaml b/fastly/products/log_explorer_insights/fixtures/enable.yaml new file mode 100644 index 000000000..2cfa1bbe4 --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"log_explorer_insights","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "218" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-ewr-kewr1740047-EWR + X-Timer: + - S1733591105.005160,VS0,VE1656 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/log_explorer_insights/fixtures/get-after-disablement.yaml b/fastly/products/log_explorer_insights/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..708db4db8 --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-ewr-kewr1740047-EWR + X-Timer: + - S1733591109.665653,VS0,VE121 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/log_explorer_insights/fixtures/get-after-enablement.yaml b/fastly/products/log_explorer_insights/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..a94b5d895 --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"log_explorer_insights","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "218" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-ewr-kewr1740047-EWR + X-Timer: + - S1733591107.720563,VS0,VE110 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/log_explorer_insights/fixtures/get-before-enablement.yaml b/fastly/products/log_explorer_insights/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..1115fb21a --- /dev/null +++ b/fastly/products/log_explorer_insights/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/log_explorer_insights/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000059-CHI, cache-ewr-kewr1740047-EWR + X-Timer: + - S1733591105.878507,VS0,VE117 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ngwaf/api.go b/fastly/products/ngwaf/api.go new file mode 100644 index 000000000..092b70fff --- /dev/null +++ b/fastly/products/ngwaf/api.go @@ -0,0 +1,86 @@ +package ngwaf + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "ngwaf" + +// ErrMissingWorkspaceID is the error returned by the Enable function +// when it is passed an EnableInput struct with a WorkspaceID field +// that is empty. +var ErrMissingWorkspaceID = fastly.NewFieldError("WorkspaceID") + +type EnableInput struct { + WorkspaceID string `json:"workspace_id"` +} + +type ConfigureInput struct { + WorkspaceID string `json:"workspace_id,omitempty"` + TrafficRamp string `json:"traffic_ramp,omitempty"` +} + +type ConfigureOutput struct { + products.ConfigureOutput `mapstructure:",squash"` + Configuration *configureOutputNested `mapstructure:"configuration"` +} + +type configureOutputNested struct { + WorkspaceID *string `mapstructure:"workspace_id,omitempty"` + TrafficRamp *string `mapstructure:"traffic_ramp,omitempty"` +} + +// Get gets the status of the Next-Gen WAF product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Next-Gen WAF product on the service. +func Enable(c *fastly.Client, serviceID string, i *EnableInput) (*products.EnableOutput, error) { + if i.WorkspaceID == "" { + return nil, ErrMissingWorkspaceID + } + + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*EnableInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + Input: i, + }) +} + +// Disable disables the Next-Gen WAF product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// GetConfiguration gets the configuration of the Next-Gen WAF product on the service. +func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, error) { + return productcore.Get[*ConfigureOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + URLComponents: []string{"configuration"}, + }) +} + +// UpdateConfiguration updates the configuration of the Next-Gen WAF product on the service. +func UpdateConfiguration(c *fastly.Client, serviceID string, i *ConfigureInput) (*ConfigureOutput, error) { + return productcore.Patch[*ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + URLComponents: []string{"configuration"}, + Input: i, + }) +} diff --git a/fastly/products/ngwaf/api_test.go b/fastly/products/ngwaf/api_test.go new file mode 100644 index 000000000..1bae43fdf --- /dev/null +++ b/fastly/products/ngwaf/api_test.go @@ -0,0 +1,96 @@ +package ngwaf_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/ngwaf" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" + + "github.com/stretchr/testify/require" +) + +var serviceID = fastly.TestDeliveryServiceID + +func TestEnableMissingWorkspaceID(t *testing.T) { + t.Parallel() + + _, err := ngwaf.Enable(nil, serviceID, &ngwaf.EnableInput{WorkspaceID: ""}) + + require.ErrorIs(t, err, ngwaf.ErrMissingWorkspaceID) +} + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: ngwaf.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *ngwaf.EnableInput]{ + OpWithInputFn: ngwaf.Enable, + Input: &ngwaf.EnableInput{WorkspaceID: fastly.TestNGWAFWorkspaceID}, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ngwaf.ConfigureOutput]{ + Phase: "default", + OpFn: ngwaf.GetConfiguration, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, output *ngwaf.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "100", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ngwaf.ConfigureOutput, *ngwaf.ConfigureInput]{ + OpFn: ngwaf.UpdateConfiguration, + Input: &ngwaf.ConfigureInput{TrafficRamp: "45"}, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, output *ngwaf.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "45", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ngwaf.ConfigureOutput]{ + Phase: "after update", + OpFn: ngwaf.GetConfiguration, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *test_utils.FunctionalTest, output *ngwaf.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "45", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: ngwaf.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablementAndConfiguration(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/ngwaf/doc.go b/fastly/products/ngwaf/doc.go new file mode 100644 index 000000000..245faf1d1 --- /dev/null +++ b/fastly/products/ngwaf/doc.go @@ -0,0 +1,3 @@ +// Package ngwaf contains API operations to enable, disable, and +// configure the Next-Gen WAF product on a service +package ngwaf diff --git a/fastly/products/ngwaf/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/ngwaf/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..931598c38 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100133-CHI, cache-nyc-kteb1890067-NYC + X-Timer: + - S1733771530.650165,VS0,VE78 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/fixtures/image_optimizer_default_settings/disable_product.yaml b/fastly/products/ngwaf/fixtures/disable.yaml similarity index 60% rename from fastly/fixtures/image_optimizer_default_settings/disable_product.yaml rename to fastly/products/ngwaf/fixtures/disable.yaml index a7c3acd2f..9e7f5c007 100644 --- a/fastly/fixtures/image_optimizer_default_settings/disable_product.yaml +++ b/fastly/products/ngwaf/fixtures/disable.yaml @@ -6,8 +6,8 @@ interactions: form: {} headers: User-Agent: - - FastlyGo/9.3.2 (+github.com/fastly/go-fastly; go1.22.2) - url: https://api.fastly.com/enabled-products/image_optimizer/services/kKJb5bOFI47uHeBVluGfX1 + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 method: DELETE response: body: "" @@ -19,11 +19,11 @@ interactions: Content-Type: - application/json Date: - - Tue, 14 May 2024 16:16:36 GMT + - Sun, 08 Dec 2024 18:16:07 GMT Pragma: - no-cache Server: - - control-gateway + - fastly control-gateway Status: - 204 No Content Strict-Transport-Security: @@ -31,15 +31,15 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 varnish + - 1.1 varnish, 1.1 varnish X-Cache: - - MISS + - MISS, MISS X-Cache-Hits: - - "0" + - 0, 0 X-Served-By: - - cache-bfi-krnt7300110-BFI + - cache-chi-klot8100133-CHI, cache-ewr-kewr1740067-EWR X-Timer: - - S1715703395.638107,VS0,VE1368 + - S1733681767.738111,VS0,VE979 status: 204 No Content code: 204 duration: "" diff --git a/fastly/products/ngwaf/fixtures/enable.yaml b/fastly/products/ngwaf/fixtures/enable.yaml new file mode 100644 index 000000000..298a236a5 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: '{"workspace_id":"alk6DTsYKHKucJCOIavaJM"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"ngwaf","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "186" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100133-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681764.059200,VS0,VE1619 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/get-after-disablement.yaml b/fastly/products/ngwaf/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..f94de87ea --- /dev/null +++ b/fastly/products/ngwaf/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:07 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100133-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681768.749543,VS0,VE116 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/get-after-enablement.yaml b/fastly/products/ngwaf/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..d323afbf2 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"ngwaf","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "186" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100133-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681766.701640,VS0,VE119 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/get-before-enablement.yaml b/fastly/products/ngwaf/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..a9f7ac874 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:04 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100133-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681764.986874,VS0,VE54 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/get-configuration-after-update.yaml b/fastly/products/ngwaf/fixtures/get-configuration-after-update.yaml new file mode 100644 index 000000000..5276b9e63 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/get-configuration-after-update.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: GET + response: + body: | + {"product":{"id":"ngwaf","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"traffic_ramp":"45","workspace_id":"alk6DTsYKHKucJCOIavaJM"},"_links":{"self":"/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "278" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100154-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681767.631795,VS0,VE97 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/get-configuration-default.yaml b/fastly/products/ngwaf/fixtures/get-configuration-default.yaml new file mode 100644 index 000000000..897b3e4d0 --- /dev/null +++ b/fastly/products/ngwaf/fixtures/get-configuration-default.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: GET + response: + body: | + {"product":{"id":"ngwaf","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"traffic_ramp":"100","workspace_id":"alk6DTsYKHKucJCOIavaJM"},"_links":{"self":"/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "279" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100154-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681766.830764,VS0,VE117 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/ngwaf/fixtures/update-configuration.yaml b/fastly/products/ngwaf/fixtures/update-configuration.yaml new file mode 100644 index 000000000..f8a56a7fc --- /dev/null +++ b/fastly/products/ngwaf/fixtures/update-configuration.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: '{"traffic_ramp":"45"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration + method: PATCH + response: + body: | + {"product":{"id":"ngwaf","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"configuration":{"traffic_ramp":"45"},"_links":{"self":"/enabled-products/v1/ngwaf/services/kKJb5bOFI47uHeBVluGfX1/configuration"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "238" + Content-Type: + - application/json + Date: + - Sun, 08 Dec 2024 18:16:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100154-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - S1733681766.958971,VS0,VE660 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/origin_inspector/api.go b/fastly/products/origin_inspector/api.go new file mode 100644 index 000000000..64429ef31 --- /dev/null +++ b/fastly/products/origin_inspector/api.go @@ -0,0 +1,36 @@ +package origin_inspector + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "origin_inspector" + +// Get gets the status of the Origin Inspector product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Origin Inspector product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Origin Inspector product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/origin_inspector/api_test.go b/fastly/products/origin_inspector/api_test.go new file mode 100644 index 000000000..0c8b839ea --- /dev/null +++ b/fastly/products/origin_inspector/api_test.go @@ -0,0 +1,55 @@ +package origin_inspector_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/origin_inspector" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: origin_inspector.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: origin_inspector.Enable, + ProductID: origin_inspector.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: origin_inspector.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/origin_inspector/doc.go b/fastly/products/origin_inspector/doc.go new file mode 100644 index 000000000..6ae21cdb5 --- /dev/null +++ b/fastly/products/origin_inspector/doc.go @@ -0,0 +1,3 @@ +// Package origin_inspector contains API operations to enable and +// disable the Origin Inspector product on a service +package origin_inspector diff --git a/fastly/products/origin_inspector/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/origin_inspector/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..f668747a1 --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000073-CHI, cache-nyc-kteb1890043-NYC + X-Timer: + - S1733771530.762519,VS0,VE79 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/origin_inspector/fixtures/disable.yaml b/fastly/products/origin_inspector/fixtures/disable.yaml new file mode 100644 index 000000000..00f980cfb --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-ewr-kewr1740069-EWR + X-Timer: + - S1733591108.052729,VS0,VE1200 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/origin_inspector/fixtures/enable.yaml b/fastly/products/origin_inspector/fixtures/enable.yaml new file mode 100644 index 000000000..154af3f10 --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"origin_inspector","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "208" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:07 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-ewr-kewr1740069-EWR + X-Timer: + - S1733591106.846744,VS0,VE2046 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/origin_inspector/fixtures/get-after-disablement.yaml b/fastly/products/origin_inspector/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..78f5cc270 --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-ewr-kewr1740069-EWR + X-Timer: + - S1733591109.261457,VS0,VE90 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/origin_inspector/fixtures/get-after-enablement.yaml b/fastly/products/origin_inspector/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..eb4da90d7 --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"origin_inspector","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "208" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-ewr-kewr1740069-EWR + X-Timer: + - S1733591108.904114,VS0,VE113 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/origin_inspector/fixtures/get-before-enablement.yaml b/fastly/products/origin_inspector/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..0751dd864 --- /dev/null +++ b/fastly/products/origin_inspector/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/origin_inspector/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:05 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-kigq8000079-CHI, cache-ewr-kewr1740069-EWR + X-Timer: + - S1733591106.788671,VS0,VE49 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/websockets/api.go b/fastly/products/websockets/api.go new file mode 100644 index 000000000..521b82218 --- /dev/null +++ b/fastly/products/websockets/api.go @@ -0,0 +1,36 @@ +package websockets + +import ( + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" +) + +const ProductID = "websockets" + +// Get gets the status of the WebSockets product on the service. +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the WebSockets product on the service. +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the WebSockets product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return productcore.Delete(&productcore.DeleteInput{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} diff --git a/fastly/products/websockets/api_test.go b/fastly/products/websockets/api_test.go new file mode 100644 index 000000000..ee5f82f35 --- /dev/null +++ b/fastly/products/websockets/api_test.go @@ -0,0 +1,55 @@ +package websockets_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/fastly/products/websockets" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*test_utils.FunctionalTest{ + productcore.NewDisableTest(&productcore.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: websockets.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "before enablement", + OpFn: websockets.Get, + ProductID: websockets.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ + OpNoInputFn: websockets.Enable, + ProductID: websockets.ProductID, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after enablement", + OpFn: websockets.Get, + ProductID: websockets.ProductID, + ServiceID: serviceID, + }), + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: websockets.Disable, + ServiceID: serviceID, + }), + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ + Phase: "after disablement", + OpFn: websockets.Get, + ProductID: websockets.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + test_utils.ExecuteFunctionalTests(t, functionalTests) +} diff --git a/fastly/products/websockets/doc.go b/fastly/products/websockets/doc.go new file mode 100644 index 000000000..2b1a0e245 --- /dev/null +++ b/fastly/products/websockets/doc.go @@ -0,0 +1,3 @@ +// Package websockets contains API operations to enable and +// disable the WebSockets product on a service +package websockets diff --git a/fastly/products/websockets/fixtures/disable-ensure-disabled-before-testing.yaml b/fastly/products/websockets/fixtures/disable-ensure-disabled-before-testing.yaml new file mode 100644 index 000000000..51da8c07a --- /dev/null +++ b/fastly/products/websockets/fixtures/disable-ensure-disabled-before-testing.yaml @@ -0,0 +1,48 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: | + {"type":"","title":"You are not authorized to perform this action","status":401,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "107" + Content-Type: + - application/json + Date: + - Mon, 09 Dec 2024 19:12:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 401 Unauthorized + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100068-CHI, cache-nyc-kteb1890099-NYC + X-Timer: + - S1733771530.762540,VS0,VE82 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/fastly/products/websockets/fixtures/disable.yaml b/fastly/products/websockets/fixtures/disable.yaml new file mode 100644 index 000000000..a1fb9a47d --- /dev/null +++ b/fastly/products/websockets/fixtures/disable.yaml @@ -0,0 +1,45 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: DELETE + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 204 No Content + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100153-CHI, cache-ewr-kewr1740033-EWR + X-Timer: + - S1733591109.183448,VS0,VE403 + status: 204 No Content + code: 204 + duration: "" diff --git a/fastly/products/websockets/fixtures/enable.yaml b/fastly/products/websockets/fixtures/enable.yaml new file mode 100644 index 000000000..707e00175 --- /dev/null +++ b/fastly/products/websockets/fixtures/enable.yaml @@ -0,0 +1,52 @@ +--- +version: 1 +interactions: +- request: + body: "null" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: PUT + response: + body: | + {"product":{"id":"websockets","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "196" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:08 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100153-CHI, cache-ewr-kewr1740033-EWR + X-Timer: + - S1733591106.159324,VS0,VE2771 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/websockets/fixtures/get-after-disablement.yaml b/fastly/products/websockets/fixtures/get-after-disablement.yaml new file mode 100644 index 000000000..35bd9d612 --- /dev/null +++ b/fastly/products/websockets/fixtures/get-after-disablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100153-CHI, cache-ewr-kewr1740033-EWR + X-Timer: + - S1733591110.600847,VS0,VE108 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/fastly/products/websockets/fixtures/get-after-enablement.yaml b/fastly/products/websockets/fixtures/get-after-enablement.yaml new file mode 100644 index 000000000..7c9f558b5 --- /dev/null +++ b/fastly/products/websockets/fixtures/get-after-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"product":{"id":"websockets","object":"product"},"service":{"id":"kKJb5bOFI47uHeBVluGfX1","object":"service"},"_links":{"self":"/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1"}} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "196" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:09 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 200 OK + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100153-CHI, cache-ewr-kewr1740033-EWR + X-Timer: + - S1733591109.972295,VS0,VE120 + status: 200 OK + code: 200 + duration: "" diff --git a/fastly/products/websockets/fixtures/get-before-enablement.yaml b/fastly/products/websockets/fixtures/get-before-enablement.yaml new file mode 100644 index 000000000..fa0ba3179 --- /dev/null +++ b/fastly/products/websockets/fixtures/get-before-enablement.yaml @@ -0,0 +1,50 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + User-Agent: + - FastlyGo/9.11.0 (+github.com/fastly/go-fastly; go1.23.4) + url: https://api.fastly.com/enabled-products/v1/websockets/services/kKJb5bOFI47uHeBVluGfX1 + method: GET + response: + body: | + {"type":"","title":"no product on service","status":400,"errors":null,"detail":""} + headers: + Accept-Ranges: + - bytes + Cache-Control: + - no-store + Content-Length: + - "83" + Content-Type: + - application/json + Date: + - Sat, 07 Dec 2024 17:05:06 GMT + Pragma: + - no-cache + Server: + - fastly control-gateway + Status: + - 400 Bad Request + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish, 1.1 varnish + X-Cache: + - MISS, MISS + X-Cache-Hits: + - 0, 0 + X-Served-By: + - cache-chi-klot8100153-CHI, cache-ewr-kewr1740033-EWR + X-Timer: + - S1733591106.090013,VS0,VE61 + status: 400 Bad Request + code: 400 + duration: "" diff --git a/go.mod b/go.mod index e393cdef5..8846fb02e 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/mitchellh/mapstructure v1.4.3 github.com/peterhellberg/link v1.1.0 + github.com/stretchr/testify v1.10.0 golang.org/x/crypto v0.31.0 golang.org/x/tools v0.15.0 honnef.co/go/tools v0.3.3 @@ -15,10 +16,13 @@ require ( require ( github.com/BurntSushi/toml v0.4.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) go 1.20 diff --git a/go.sum b/go.sum index c8d2815bb..763c77f29 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -18,6 +20,10 @@ github.com/peterhellberg/link v1.1.0 h1:s2+RH8EGuI/mI4QwrWGSYQCRz7uNgip9BaM04HKu github.com/peterhellberg/link v1.1.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= @@ -32,5 +38,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= diff --git a/internal/productcore/api_delete.go b/internal/productcore/api_delete.go new file mode 100644 index 000000000..d73a9b95c --- /dev/null +++ b/internal/productcore/api_delete.go @@ -0,0 +1,32 @@ +package productcore + +import "github.com/fastly/go-fastly/v9/fastly" + +// DeleteInput specifies the information needed for the Delete +// function to perform the operation. +type DeleteInput struct { + Client *fastly.Client + ProductID string + ServiceID string + URLComponents []string +} + +// Delete implements a product-specific 'delete' operation. Since this +// operation does not accept any input or produce any output (other +// than a potential error), this function does not have any type +// parameters. +func Delete(i *DeleteInput) error { + if i.ServiceID == "" { + return fastly.ErrMissingServiceID + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.Delete(path, nil) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} diff --git a/internal/productcore/api_get.go b/internal/productcore/api_get.go new file mode 100644 index 000000000..3c0258c14 --- /dev/null +++ b/internal/productcore/api_get.go @@ -0,0 +1,36 @@ +package productcore + +import "github.com/fastly/go-fastly/v9/fastly" + +// GetInput specifies the information needed for the Get() +// function to perform the operation. +type GetInput struct { + Client *fastly.Client + ProductID string + ServiceID string + URLComponents []string +} + +// Get implements a product-specific 'get' operation. +// +// This function requires a type parameter which is a pointer to an +// struct which matches the ProductOutput interface, and that type +// is used to construct, populate, and return the output present in +// the response body. +func Get[O ProductOutput](i *GetInput) (o O, err error) { + if i.ServiceID == "" { + err = fastly.ErrMissingServiceID + return + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.GetJSON(path, nil) + if err != nil { + return + } + defer resp.Body.Close() + + err = fastly.DecodeBodyMap(resp.Body, &o) + return +} diff --git a/internal/productcore/api_patch.go b/internal/productcore/api_patch.go new file mode 100644 index 000000000..b46c5d254 --- /dev/null +++ b/internal/productcore/api_patch.go @@ -0,0 +1,44 @@ +package productcore + +import "github.com/fastly/go-fastly/v9/fastly" + +// PatchInput specifies the information needed for the Patch() +// function to perform the operation. +// +// Because Patch operations accept input, this struct has a type +// parameter used to specify the type of the input structure. +type PatchInput[I any] struct { + Client *fastly.Client + ProductID string + ServiceID string + URLComponents []string + Input I +} + +// Patch implements a product-specific 'patch' operation. +// +// This function requires the same type parameter as the PatchInput +// struct; the input type parameter is used to marshal the input data +// into the request body (encoded as JSON). +// +// It also requires a type parameter which is a pointer to an +// struct which matches the ProductOutput interface, and that type +// is used to construct, populate, and return the output present in +// the response body. +func Patch[O ProductOutput, I any](i *PatchInput[I]) (o O, err error) { + if i.ServiceID == "" { + err = fastly.ErrMissingServiceID + return + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.PatchJSON(path, i.Input, nil) + if err != nil { + return + } + defer resp.Body.Close() + + err = fastly.DecodeBodyMap(resp.Body, &o) + return +} diff --git a/internal/productcore/api_put.go b/internal/productcore/api_put.go new file mode 100644 index 000000000..e3849ec24 --- /dev/null +++ b/internal/productcore/api_put.go @@ -0,0 +1,44 @@ +package productcore + +import "github.com/fastly/go-fastly/v9/fastly" + +// PutInput specifies the information needed for the Put() +// function to perform the operation. +// +// Because Put operations accept input, this struct has a type +// parameter used to specify the type of the input structure. +type PutInput[I any] struct { + Client *fastly.Client + ProductID string + ServiceID string + URLComponents []string + Input I +} + +// Put implements a product-specific 'put' operation. +// +// This function requires the same type parameter as the PutInput +// struct; the input type parameter is used to marshal the input data +// into the request body (encoded as JSON). +// +// It also requires a type parameter which is a pointer to an +// struct which matches the ProductOutput interface, and that type +// is used to construct, populate, and return the output present in +// the response body. +func Put[O ProductOutput, I any](i *PutInput[I]) (o O, err error) { + if i.ServiceID == "" { + err = fastly.ErrMissingServiceID + return + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.PutJSON(path, i.Input, nil) + if err != nil { + return + } + defer resp.Body.Close() + + err = fastly.DecodeBodyMap(resp.Body, &o) + return +} diff --git a/internal/productcore/doc.go b/internal/productcore/doc.go new file mode 100644 index 000000000..423cdaa01 --- /dev/null +++ b/internal/productcore/doc.go @@ -0,0 +1,5 @@ +// Package productcore provides a group of generic HTTP operation +// wrappers which are used to compose API operations on products, and +// a group of constructors used to create FunctionalTest objects for +// testing those API operations +package productcore diff --git a/internal/productcore/functional_test_disable.go b/internal/productcore/functional_test_disable.go new file mode 100644 index 000000000..ce327e1c6 --- /dev/null +++ b/internal/productcore/functional_test_disable.go @@ -0,0 +1,59 @@ +package productcore + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +// DisableTestInput specifies the information needed for the +// NewDisableTest constructor to construct a FunctionalTest object. +type DisableTestInput struct { + // Phase is used to distinguish between multiple Disable test + // cases in a sequence of test cases; it is included in the + // test case's Name and Operation fields + Phase string + // OpFn is the function to be invoked to perform the + // disablement + OpFn func(*fastly.Client, string) error + // ServiceID identifies the service on which the product + // should be disabled + ServiceID string + // ExpectFailure specifies whether this test case is expected + // to fail + ExpectFailure bool + // IgnoreFailure specifies that errors returned from OpFn + // should be ignored + IgnoreFailure bool +} + +// NewDisableTest constructs a FunctionalTest object as specified by +// its input. +func NewDisableTest(i *DisableTestInput) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} + + if i.Phase != "" { + r.Name = "disable " + i.Phase + r.Operation = "disable-" + strings.ReplaceAll(i.Phase, " ", "-") + } else { + r.Name = "disable" + r.Operation = "disable" + } + + r.TestFn = func(_ *testing.T, _ *test_utils.FunctionalTest, c *fastly.Client) error { + err := i.OpFn(c, i.ServiceID) + return err + } + + if i.ExpectFailure { + // FIXME: not clear what to do here, as the returned + // error may not be consistent but is probably 404 + r.WantNoError = true + } else if !i.IgnoreFailure { + r.WantNoError = true + } + + return &r +} diff --git a/internal/productcore/functional_test_enable.go b/internal/productcore/functional_test_enable.go new file mode 100644 index 000000000..f17572c2c --- /dev/null +++ b/internal/productcore/functional_test_enable.go @@ -0,0 +1,107 @@ +package productcore + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +// EnableTestInput specifies the information needed for the +// NewEnableTest constructor to construct a FunctionalTest object. +// +// Because Enable operations accept input and produce output, this +// struct has two type parameters used to specify the types of the +// input and output. The output type parameter is constrained to match +// the ProductOutput interface (in this package) so that the test case +// can validate the common portions of the output. +type EnableTestInput[O ProductOutput, I any] struct { + // Phase is used to distinguish between multiple Enable test + // cases in a sequence of test cases; it is included in the + // test case's Name and Operation fields + Phase string + // OpNoInputFn is the function to be invoked to perform the + // enable operation, when no input is required (I == NulInput) + OpNoInputFn func(*fastly.Client, string) (O, error) + // OpWithInputFn is the function to be invoked to perform the + // enable operation, when input is required (I != NulInput) + OpWithInputFn func(*fastly.Client, string, I) (O, error) + // Input is the input to be provided to OpWithInputFn + Input I + // ProductID identifies the product for which information + // should be obtained on the service; note that it is only + // used to validate the ProductID in the output from OpFn (if + // any), it is not provided to OpNoInputFn or OpWithInputFn + ProductID string + // ServiceID identifies the service on which the product + // information should be obtained + ServiceID string + // ExpectFailure specifies whether this test case is expected + // to fail + ExpectFailure bool + // IgnoreFailure specifies that errors returned from + // OpNoInputFn/OpWithInputFn should be ignored + IgnoreFailure bool + // CheckOutputFn specifies a function whch will be invoked if + // OpNoInputFn/OpWithInputFn return normally; it can be used + // to perform validation of the contents of the output + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) +} + +// NewEnableTest constructs a FunctionalTest object as specified by its +// input. +// +// This function requires the same input type parameter as the +// EnableTestInput struct, and that type is used to determine whether +// OpNoInputFn or OpWithInputFn are called to perform the test. +// +// This function requires the same output type parameter as the +// EnableTestInput struct, and that type is used to construct, +// populate, and validate the output present in the response body. +func NewEnableTest[O ProductOutput, I any](i *EnableTestInput[O, I]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} + + if i.Phase != "" { + r.Name = "enable " + i.Phase + r.Operation = "enable-" + strings.ReplaceAll(i.Phase, " ", "-") + } else { + r.Name = "enable" + r.Operation = "enable" + } + + switch any(i.Input).(type) { + case *NullInput: + r.TestFn = func(t *testing.T, tc *test_utils.FunctionalTest, c *fastly.Client) error { + result, err := i.OpNoInputFn(c, i.ServiceID) + if err == nil { + validateOutput(t, tc, result, i.ProductID, i.ServiceID) + if i.CheckOutputFn != nil { + i.CheckOutputFn(t, tc, result) + } + } + return err + } + default: + r.TestFn = func(t *testing.T, tc *test_utils.FunctionalTest, c *fastly.Client) error { + result, err := i.OpWithInputFn(c, i.ServiceID, i.Input) + if err == nil { + validateOutput(t, tc, result, i.ProductID, i.ServiceID) + if i.CheckOutputFn != nil { + i.CheckOutputFn(t, tc, result) + } + } + return err + } + } + + if i.ExpectFailure { + // FIXME unclear what an 'expected' failure would be + // for this operation + r.WantNoError = true + } else if !i.IgnoreFailure { + r.WantNoError = true + } + + return &r +} diff --git a/internal/productcore/functional_test_get.go b/internal/productcore/functional_test_get.go new file mode 100644 index 000000000..636f31cd8 --- /dev/null +++ b/internal/productcore/functional_test_get.go @@ -0,0 +1,96 @@ +package productcore + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" + "github.com/stretchr/testify/require" +) + +// GetTestInput specifies the information needed for the NewGetTest +// constructor to construct a FunctionalTest object. +// +// Because Get operations produce output, this struct has a type +// parameter used to specify the type of the output. The type +// parameter is constrained to match the ProductOutput interface (in +// this package) so that the test case can validate the common +// portions of the output. +type GetTestInput[O ProductOutput] struct { + // Phase is used to distinguish between multiple Get test + // cases in a sequence of test cases; it is included in the + // test case's Name and Operation fields + Phase string + // OpFn is the function to be invoked to perform the + // get operation + OpFn func(*fastly.Client, string) (O, error) + // ProductID identifies the product for which information + // should be obtained on the service; note that it is only + // used to validate the ProductID in the output from OpFn (if + // any), it is not provided to OpFn + ProductID string + // ServiceID identifies the service on which the product + // information should be obtained + ServiceID string + // ExpectFailure specifies whether this test case is expected + // to fail + ExpectFailure bool + // IgnoreFailure specifies that errors returned from OpFn + // should be ignored + IgnoreFailure bool + // CheckOutputFn specifies a function whch will be invoked if + // the OpFn returns normally; it can be used to perform + // validation of the contents of the output + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) +} + +// NewGetTest constructs a FunctionalTest object as specified by its +// input. +// +// This function requires the same type parameter as the GetTestInput +// struct, and that type is used to construct, populate, and validate +// the output present in the response body. +// +// If the input indicates that failure is expected, the test case will +// ensure that the error received from the API matches the documented +// error returned when a product is not enabled on a service. If any +// other error is returned by the API, the test case will report +// failure. +func NewGetTest[O ProductOutput](i *GetTestInput[O]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} + + if i.Phase != "" { + r.Name = "get status " + i.Phase + r.Operation = "get-" + strings.ReplaceAll(i.Phase, " ", "-") + } else { + r.Name = "get status" + r.Operation = "get" + } + + r.TestFn = func(t *testing.T, tc *test_utils.FunctionalTest, c *fastly.Client) error { + result, err := i.OpFn(c, i.ServiceID) + if err == nil { + validateOutput(t, tc, result, i.ProductID, i.ServiceID) + if i.CheckOutputFn != nil { + i.CheckOutputFn(t, tc, result) + } + } + return err + } + + if i.ExpectFailure { + r.CheckErrorFn = func(t *testing.T, testName string, err error) { + // the API returns "Bad Request" instead of + // "Not Found" when a product has not been + // enabled on a service + var herr *fastly.HTTPError + require.ErrorAs(t, err, &herr, testName) + require.Truef(t, herr.IsBadRequest(), "%s expected HTTP 'Bad Request'", testName) + } + } else if !i.IgnoreFailure { + r.WantNoError = true + } + + return &r +} diff --git a/internal/productcore/functional_test_get_configuration.go b/internal/productcore/functional_test_get_configuration.go new file mode 100644 index 000000000..f829c7b08 --- /dev/null +++ b/internal/productcore/functional_test_get_configuration.go @@ -0,0 +1,81 @@ +package productcore + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +// GetConfigurationTestInput specifies the information needed for the +// NewGetConfigurationTest constructor to construct a FunctionalTest +// object. +// +// Because GetConfiguration operations produce output, this struct has +// a type parameter used to specify the type of the output. The type +// parameter is constrained to match the ProductOutput interface (in +// this package) so that the test case can validate the common +// portions of the output. +type GetConfigurationTestInput[O ProductOutput] struct { + // Phase is used to distinguish between multiple + // GetConfiguration test cases in a sequence of test cases; it + // is included in the test case's Name and Operation fields + Phase string + // OpFn is the function to be invoked to perform the + // get operation + OpFn func(*fastly.Client, string) (O, error) + // ProductID identifies the product for which information + // should be obtained on the service; note that it is only + // used to validate the ProductID in the output from OpFn (if + // any), it is not provided to OpFn + ProductID string + // ServiceID identifies the service on which the product + // information should be obtained + ServiceID string + // ExpectFailure specifies whether this test case is expected + // to fail + ExpectFailure bool + // IgnoreFailure specifies that errors returned from OpFn + // should be ignored + IgnoreFailure bool + // CheckOutputFn specifies a function whch will be invoked if + // the OpFn returns normally; it can be used to perform + // validation of the contents of the output + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) +} + +// NewGetConfigurationTest constructs a FunctionalTest object as +// specified by its input. +func NewGetConfigurationTest[O ProductOutput](i *GetConfigurationTestInput[O]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} + + if i.Phase != "" { + r.Name = "get configuration " + i.Phase + r.Operation = "get-configuration-" + strings.ReplaceAll(i.Phase, " ", "-") + } else { + r.Name = "get configuration" + r.Operation = "get-configuration" + } + + r.TestFn = func(t *testing.T, tc *test_utils.FunctionalTest, c *fastly.Client) error { + result, err := i.OpFn(c, i.ServiceID) + if err == nil { + validateOutput(t, tc, result, i.ProductID, i.ServiceID) + if i.CheckOutputFn != nil { + i.CheckOutputFn(t, tc, result) + } + } + return err + } + + if i.ExpectFailure { + // FIXME need to determine the expected error here, + // probably 404 + r.WantNoError = true + } else if !i.IgnoreFailure { + r.WantNoError = true + } + + return &r +} diff --git a/internal/productcore/functional_test_update_configuration.go b/internal/productcore/functional_test_update_configuration.go new file mode 100644 index 000000000..1d2266129 --- /dev/null +++ b/internal/productcore/functional_test_update_configuration.go @@ -0,0 +1,92 @@ +package productcore + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" +) + +// UpdateConfigurationTestInput specifies the information needed for +// the NewUpdateConfigurationTest constructor to construct a +// FunctionalTest object. +// +// Because UpdateConfiguration operations accept input and produce +// output, this struct has two type parameters used to specify the +// types of the input and output. The output type parameter is +// constrained to match the ProductOutput interface (in this package) +// so that the test case can validate the common portions of the +// output. +type UpdateConfigurationTestInput[O ProductOutput, I any] struct { + // Phase is used to distinguish between multiple Enable test + // cases in a sequence of test cases; it is included in the + // test case's Name and Operation fields + Phase string + // OpFn is the function to be invoked to perform the + // operation + OpFn func(*fastly.Client, string, I) (O, error) + // Input is the input to be provided to OpFn + Input I + // ProductID identifies the product for which information + // should be obtained on the service; note that it is only + // used to validate the ProductID in the output from OpFn (if + // any), it is not provided to OpFn + ProductID string + // ServiceID identifies the service on which the product + // information should be obtained + ServiceID string + // ExpectFailure specifies whether this test case is expected + // to fail + ExpectFailure bool + // IgnoreFailure specifies that errors returned from OpFn + // should be ignored + IgnoreFailure bool + // CheckOutputFn specifies a function whch will be invoked if + // the OpFn returns normally; it can be used to perform + // validation of the contents of the output + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) +} + +// NewUpdateConfigurationTest constructs a FunctionalTest object as +// specified by its input. +// +// This function requires the same input type parameter as the +// UpdateConfigurationTestInput struct. +// +// This function requires the same output type parameter as the +// UpdateConfigurationTestInput struct, and that type is used to +// construct, populate, and validate the output present in the +// response body. +func NewUpdateConfigurationTest[O ProductOutput, I any](i *UpdateConfigurationTestInput[O, I]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} + + if i.Phase != "" { + r.Name = "update configuration " + i.Phase + r.Operation = "update-configuration-" + strings.ReplaceAll(i.Phase, " ", "-") + } else { + r.Name = "update configuration" + r.Operation = "update-configuration" + } + + r.TestFn = func(t *testing.T, tc *test_utils.FunctionalTest, c *fastly.Client) error { + result, err := i.OpFn(c, i.ServiceID, i.Input) + if err == nil { + validateOutput(t, tc, result, i.ProductID, i.ServiceID) + if i.CheckOutputFn != nil { + i.CheckOutputFn(t, tc, result) + } + } + return err + } + + if i.ExpectFailure { + // FIXME unclear what an 'expected' failure would be + // for this operation + r.WantNoError = true + } else if !i.IgnoreFailure { + r.WantNoError = true + } + + return &r +} diff --git a/internal/productcore/functional_test_utils.go b/internal/productcore/functional_test_utils.go new file mode 100644 index 000000000..e758a3446 --- /dev/null +++ b/internal/productcore/functional_test_utils.go @@ -0,0 +1,23 @@ +package productcore + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/internal/test_utils" + "github.com/stretchr/testify/require" +) + +// validateOutput provides common validation for all responses to +// product-specific API operations. +// +// All of the operations return a JSON object containing the ProductID +// and ServiceID on which the operation was invoked; this function +// confirms that they were returned and that they have the expected +// values. +func validateOutput(t *testing.T, tc *test_utils.FunctionalTest, o ProductOutput, productID, serviceID string) { + require.NotNilf(t, o, "test '%s'", tc.Name) + require.NotNilf(t, o.ProductID(), "test '%s'", tc.Name) + require.NotNilf(t, o.ServiceID(), "test '%s'", tc.Name) + require.Equalf(t, productID, *o.ProductID(), "test '%s'", tc.Name) + require.Equalf(t, serviceID, *o.ServiceID(), "test '%s'", tc.Name) +} diff --git a/internal/productcore/productcore_test.go b/internal/productcore/productcore_test.go new file mode 100644 index 000000000..272ce1d93 --- /dev/null +++ b/internal/productcore/productcore_test.go @@ -0,0 +1,49 @@ +package productcore_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/productcore" + "github.com/stretchr/testify/require" +) + +func TestDeleteMissingServiceID(t *testing.T) { + t.Parallel() + + err := productcore.Delete(&productcore.DeleteInput{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestGetMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := productcore.Get[*productcore.NullOutput](&productcore.GetInput{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestPatchMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := productcore.Patch[*productcore.NullOutput](&productcore.PatchInput[*productcore.NullInput]{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestPutMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := productcore.Put[*productcore.NullOutput](&productcore.PutInput[*productcore.NullInput]{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} diff --git a/internal/productcore/types.go b/internal/productcore/types.go new file mode 100644 index 000000000..382b05ea7 --- /dev/null +++ b/internal/productcore/types.go @@ -0,0 +1,34 @@ +package productcore + +// ProductOutput is an interface used to constrain the 'O' type +// parameter of the functions in this package. Use of this interface +// allows the FunctionalTest constructors to apply common validation +// steps to the output received from an API operation, eliminating the +// need to duplicate that validation in every FunctionalTest case, and +// ensures that the API operation functions only accept types which +// would also be accepted by the FunctionalTest constructors. +// +// This interface matches the methods of the EnableOutput and +// ConfigureOutput structs in the fastly/products package. +type ProductOutput interface { + ProductID() *string + ServiceID() *string +} + +// NullInput is used to indicate to the generic FunctionalTest +// constructors that the operation being tested does not accept an +// Input struct +type NullInput struct{} + +// NullOutput is used to indicate to the generic FunctionalTest +// constructors that the operation being tested does not produce an +// Output struct +type NullOutput struct{} + +func (o *NullOutput) ProductID() *string { + return nil +} + +func (o *NullOutput) ServiceID() *string { + return nil +} diff --git a/internal/productcore/utils.go b/internal/productcore/utils.go new file mode 100644 index 000000000..4a83feeac --- /dev/null +++ b/internal/productcore/utils.go @@ -0,0 +1,17 @@ +package productcore + +import "github.com/fastly/go-fastly/v9/fastly" + +func makeURL(productID, serviceID string, subComponents []string) string { + path := []string{"enabled-products", "v1", productID} + + if serviceID != "" { + path = append(path, "services", serviceID) + } + + if len(subComponents) > 0 { + path = append(path, subComponents...) + } + + return fastly.ToSafeURL(path...) +} diff --git a/internal/test_utils/doc.go b/internal/test_utils/doc.go new file mode 100644 index 000000000..ddb5247cd --- /dev/null +++ b/internal/test_utils/doc.go @@ -0,0 +1,3 @@ +// Package test_utils contains types and functions used to simplify +// creation and execution of unit and functional tests +package test_utils diff --git a/internal/test_utils/functional.go b/internal/test_utils/functional.go new file mode 100644 index 000000000..d42cc4a92 --- /dev/null +++ b/internal/test_utils/functional.go @@ -0,0 +1,51 @@ +package test_utils + +import ( + "fmt" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/stretchr/testify/require" +) + +type FunctionalTest struct { + // Name is the name of the test case, used in error messages + Name string + // Operation is the operation being performed, which will be + // used to construct the recorded fixture file's name + Operation string + // TestFn is the function to be called to run the test + TestFn func(*testing.T, *FunctionalTest, *fastly.Client) error + // WantNoError indicates that the test case should fail if any + // error is returned by TestFn + WantNoError bool + // WantError indicates the error (value, not type) that must + // be returned by TestFn for this test case + WantError error + // CheckErrorFn is a function which can be used to perform + // additional validation of the error returned by TestFn; the + // function will be passed a formatted string containing the + // test case's name, along with the returned error + CheckErrorFn func(*testing.T, string, error) +} + +func ExecuteFunctionalTests(t *testing.T, tests []*FunctionalTest) { + t.Parallel() + + var err error + + for _, tc := range tests { + fastly.Record(t, tc.Operation, func(c *fastly.Client) { + err = tc.TestFn(t, tc, c) + }) + if tc.WantNoError { + require.NoErrorf(t, err, "test '%s'", tc.Name) + } + if tc.WantError != nil { + require.ErrorIsf(t, err, tc.WantError, "test '%s'", tc.Name) + } + if tc.CheckErrorFn != nil { + tc.CheckErrorFn(t, fmt.Sprintf("test '%s", tc.Name), err) + } + } +} diff --git a/scripts/check-imports.sh b/scripts/check-imports.sh index 413a2fab9..9721cb169 100755 --- a/scripts/check-imports.sh +++ b/scripts/check-imports.sh @@ -2,7 +2,7 @@ echo "==> Checking that code complies with goimports requirements..." -goimports_files=$(goimports -d -l {fastly,tools}) +goimports_files=$(goimports -d -l ./...) if [[ -n ${goimports_files} ]]; then echo 'goimports needs to be run on the following files:' echo " ===== "