From 4abff11401ec06739241e3d4f5d62004d1349d13 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Sun, 8 Dec 2024 13:11:54 -0500 Subject: [PATCH 1/8] feat(products): Product-specific enablement and configuration. Product-specific enablement and configuration operations have been added under the 'fastly/products/ package path in this module. These are intended to replace the non-specific 'GetProduct', 'EnableProduct', and 'DisableProduct' operations, which have been marked as deprecated. By adding these operations, support for products which require configuration during enablement (Next-Gen WAF), and/or support configuration after enablement (Next-Gen WAF and DDoS Protection) is now available. The operations for those products have product-specific Input and Output structures which carry the additional attributes supported by the products. In addition, the functional tests for all product enablement operations have been enhanced to more thoroughly test the operations. --- Makefile | 62 +++++----- fastly/client.go | 14 +++ fastly/errors.go | 9 +- fastly/fastly_test_utils.go | 43 +++++++ fastly/product_enablement.go | 9 ++ fastly/products/api_output.go | 38 +++++++ fastly/products/bot_management/api.go | 38 +++++++ fastly/products/bot_management/api_test.go | 57 ++++++++++ fastly/products/bot_management/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../bot_management/fixtures/disable.yaml | 45 ++++++++ .../bot_management/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/brotli_compression/api.go | 38 +++++++ .../products/brotli_compression/api_test.go | 57 ++++++++++ fastly/products/brotli_compression/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../brotli_compression/fixtures/disable.yaml | 45 ++++++++ .../brotli_compression/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/ddos_protection/api.go | 81 +++++++++++++ fastly/products/ddos_protection/api_test.go | 97 ++++++++++++++++ fastly/products/ddos_protection/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../ddos_protection/fixtures/disable.yaml | 45 ++++++++ .../ddos_protection/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ .../get-configuration-after-update.yaml | 50 +++++++++ .../fixtures/get-configuration-default.yaml | 50 +++++++++ .../fixtures/update-configuration.yaml | 52 +++++++++ fastly/products/doc.go | 4 + fastly/products/domain_inspector/api.go | 38 +++++++ fastly/products/domain_inspector/api_test.go | 57 ++++++++++ fastly/products/domain_inspector/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../domain_inspector/fixtures/disable.yaml | 45 ++++++++ .../domain_inspector/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/fanout/api.go | 38 +++++++ fastly/products/fanout/api_test.go | 57 ++++++++++ fastly/products/fanout/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ fastly/products/fanout/fixtures/disable.yaml | 45 ++++++++ fastly/products/fanout/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fanout/fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/image_optimizer/api.go | 38 +++++++ fastly/products/image_optimizer/api_test.go | 57 ++++++++++ fastly/products/image_optimizer/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../image_optimizer/fixtures/disable.yaml | 45 ++++++++ .../image_optimizer/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/log_explorer_insights/api.go | 38 +++++++ .../log_explorer_insights/api_test.go | 57 ++++++++++ fastly/products/log_explorer_insights/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../fixtures/disable.yaml | 45 ++++++++ .../fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/ngwaf/api.go | 88 +++++++++++++++ fastly/products/ngwaf/api_test.go | 98 ++++++++++++++++ fastly/products/ngwaf/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ fastly/products/ngwaf/fixtures/disable.yaml | 45 ++++++++ fastly/products/ngwaf/fixtures/enable.yaml | 52 +++++++++ .../ngwaf/fixtures/get-after-disablement.yaml | 50 +++++++++ .../ngwaf/fixtures/get-after-enablement.yaml | 50 +++++++++ .../ngwaf/fixtures/get-before-enablement.yaml | 50 +++++++++ .../get-configuration-after-update.yaml | 50 +++++++++ .../fixtures/get-configuration-default.yaml | 50 +++++++++ .../ngwaf/fixtures/update-configuration.yaml | 52 +++++++++ fastly/products/origin_inspector/api.go | 38 +++++++ fastly/products/origin_inspector/api_test.go | 57 ++++++++++ fastly/products/origin_inspector/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../origin_inspector/fixtures/disable.yaml | 45 ++++++++ .../origin_inspector/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ fastly/products/websockets/api.go | 38 +++++++ fastly/products/websockets/api_test.go | 57 ++++++++++ fastly/products/websockets/doc.go | 3 + ...isable-ensure-disabled-before-testing.yaml | 48 ++++++++ .../products/websockets/fixtures/disable.yaml | 45 ++++++++ .../products/websockets/fixtures/enable.yaml | 52 +++++++++ .../fixtures/get-after-disablement.yaml | 50 +++++++++ .../fixtures/get-after-enablement.yaml | 50 +++++++++ .../fixtures/get-before-enablement.yaml | 50 +++++++++ go.mod | 4 + go.sum | 8 ++ internal/products/api_base.go | 6 + internal/products/api_delete.go | 32 ++++++ internal/products/api_get.go | 45 ++++++++ internal/products/api_patch.go | 48 ++++++++ internal/products/api_put.go | 48 ++++++++ internal/products/doc.go | 5 + internal/products/functional_test_disable.go | 58 ++++++++++ internal/products/functional_test_enable.go | 106 ++++++++++++++++++ internal/products/functional_test_get.go | 95 ++++++++++++++++ .../functional_test_get_configuration.go | 80 +++++++++++++ .../functional_test_update_configuration.go | 91 +++++++++++++++ internal/products/functional_test_utils.go | 23 ++++ internal/products/products_test.go | 49 ++++++++ internal/products/types.go | 15 +++ internal/products/utils.go | 17 +++ scripts/check-imports.sh | 2 +- 121 files changed, 5284 insertions(+), 35 deletions(-) create mode 100644 fastly/products/api_output.go create mode 100644 fastly/products/bot_management/api.go create mode 100644 fastly/products/bot_management/api_test.go create mode 100644 fastly/products/bot_management/doc.go create mode 100644 fastly/products/bot_management/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/bot_management/fixtures/disable.yaml create mode 100644 fastly/products/bot_management/fixtures/enable.yaml create mode 100644 fastly/products/bot_management/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/bot_management/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/bot_management/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/brotli_compression/api.go create mode 100644 fastly/products/brotli_compression/api_test.go create mode 100644 fastly/products/brotli_compression/doc.go create mode 100644 fastly/products/brotli_compression/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/brotli_compression/fixtures/disable.yaml create mode 100644 fastly/products/brotli_compression/fixtures/enable.yaml create mode 100644 fastly/products/brotli_compression/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/brotli_compression/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/brotli_compression/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/ddos_protection/api.go create mode 100644 fastly/products/ddos_protection/api_test.go create mode 100644 fastly/products/ddos_protection/doc.go create mode 100644 fastly/products/ddos_protection/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/ddos_protection/fixtures/disable.yaml create mode 100644 fastly/products/ddos_protection/fixtures/enable.yaml create mode 100644 fastly/products/ddos_protection/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/ddos_protection/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/ddos_protection/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/ddos_protection/fixtures/get-configuration-after-update.yaml create mode 100644 fastly/products/ddos_protection/fixtures/get-configuration-default.yaml create mode 100644 fastly/products/ddos_protection/fixtures/update-configuration.yaml create mode 100644 fastly/products/doc.go create mode 100644 fastly/products/domain_inspector/api.go create mode 100644 fastly/products/domain_inspector/api_test.go create mode 100644 fastly/products/domain_inspector/doc.go create mode 100644 fastly/products/domain_inspector/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/domain_inspector/fixtures/disable.yaml create mode 100644 fastly/products/domain_inspector/fixtures/enable.yaml create mode 100644 fastly/products/domain_inspector/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/domain_inspector/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/domain_inspector/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/fanout/api.go create mode 100644 fastly/products/fanout/api_test.go create mode 100644 fastly/products/fanout/doc.go create mode 100644 fastly/products/fanout/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/fanout/fixtures/disable.yaml create mode 100644 fastly/products/fanout/fixtures/enable.yaml create mode 100644 fastly/products/fanout/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/fanout/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/fanout/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/image_optimizer/api.go create mode 100644 fastly/products/image_optimizer/api_test.go create mode 100644 fastly/products/image_optimizer/doc.go create mode 100644 fastly/products/image_optimizer/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/image_optimizer/fixtures/disable.yaml create mode 100644 fastly/products/image_optimizer/fixtures/enable.yaml create mode 100644 fastly/products/image_optimizer/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/image_optimizer/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/image_optimizer/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/log_explorer_insights/api.go create mode 100644 fastly/products/log_explorer_insights/api_test.go create mode 100644 fastly/products/log_explorer_insights/doc.go create mode 100644 fastly/products/log_explorer_insights/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/log_explorer_insights/fixtures/disable.yaml create mode 100644 fastly/products/log_explorer_insights/fixtures/enable.yaml create mode 100644 fastly/products/log_explorer_insights/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/log_explorer_insights/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/log_explorer_insights/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/ngwaf/api.go create mode 100644 fastly/products/ngwaf/api_test.go create mode 100644 fastly/products/ngwaf/doc.go create mode 100644 fastly/products/ngwaf/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/ngwaf/fixtures/disable.yaml create mode 100644 fastly/products/ngwaf/fixtures/enable.yaml create mode 100644 fastly/products/ngwaf/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/ngwaf/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/ngwaf/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/ngwaf/fixtures/get-configuration-after-update.yaml create mode 100644 fastly/products/ngwaf/fixtures/get-configuration-default.yaml create mode 100644 fastly/products/ngwaf/fixtures/update-configuration.yaml create mode 100644 fastly/products/origin_inspector/api.go create mode 100644 fastly/products/origin_inspector/api_test.go create mode 100644 fastly/products/origin_inspector/doc.go create mode 100644 fastly/products/origin_inspector/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/origin_inspector/fixtures/disable.yaml create mode 100644 fastly/products/origin_inspector/fixtures/enable.yaml create mode 100644 fastly/products/origin_inspector/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/origin_inspector/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/origin_inspector/fixtures/get-before-enablement.yaml create mode 100644 fastly/products/websockets/api.go create mode 100644 fastly/products/websockets/api_test.go create mode 100644 fastly/products/websockets/doc.go create mode 100644 fastly/products/websockets/fixtures/disable-ensure-disabled-before-testing.yaml create mode 100644 fastly/products/websockets/fixtures/disable.yaml create mode 100644 fastly/products/websockets/fixtures/enable.yaml create mode 100644 fastly/products/websockets/fixtures/get-after-disablement.yaml create mode 100644 fastly/products/websockets/fixtures/get-after-enablement.yaml create mode 100644 fastly/products/websockets/fixtures/get-before-enablement.yaml create mode 100644 internal/products/api_base.go create mode 100644 internal/products/api_delete.go create mode 100644 internal/products/api_get.go create mode 100644 internal/products/api_patch.go create mode 100644 internal/products/api_put.go create mode 100644 internal/products/doc.go create mode 100644 internal/products/functional_test_disable.go create mode 100644 internal/products/functional_test_enable.go create mode 100644 internal/products/functional_test_get.go create mode 100644 internal/products/functional_test_get_configuration.go create mode 100644 internal/products/functional_test_update_configuration.go create mode 100644 internal/products/functional_test_utils.go create mode 100644 internal/products/products_test.go create mode 100644 internal/products/types.go create mode 100644 internal/products/utils.go 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/fastly_test_utils.go b/fastly/fastly_test_utils.go index 1d8fb8731..ab3132595 100644 --- a/fastly/fastly_test_utils.go +++ b/fastly/fastly_test_utils.go @@ -8,6 +8,7 @@ import ( "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" + "github.com/stretchr/testify/require" ) // TestClient is the test client. @@ -666,3 +667,45 @@ Wm7DCfrPNGVwFWUQOmsPue9rZBgO -----END CERTIFICATE----- ` } + +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, *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 { + Record(t, tc.Operation, func(c *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/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..47a528bcb --- /dev/null +++ b/fastly/products/bot_management/api.go @@ -0,0 +1,38 @@ +package bot_management + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "bot_management" + +// Get gets the status of the Bot Management product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Bot Management product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Bot Management product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..d248875e0 --- /dev/null +++ b/fastly/products/bot_management/api_test.go @@ -0,0 +1,57 @@ +package bot_management_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/bot_management" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..5abc6e1bf --- /dev/null +++ b/fastly/products/brotli_compression/api.go @@ -0,0 +1,38 @@ +package brotli_compression + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "brotli_compression" + +// Get gets the status of the Brotli Compression product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Brotli Compression product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Brotli Compression product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..e9083620d --- /dev/null +++ b/fastly/products/brotli_compression/api_test.go @@ -0,0 +1,57 @@ +package brotli_compression_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/brotli_compression" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..036dc83de --- /dev/null +++ b/fastly/products/ddos_protection/api.go @@ -0,0 +1,81 @@ +package ddos_protection + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +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 { + fp.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) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the DDoS Protection product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the DDoS Protection product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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 ip.Get(&ip.GetInput[ConfigureOutput]{ + 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 ip.Patch(&ip.PatchInput[ConfigureInput, ConfigureOutput]{ + 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..a3dc34b10 --- /dev/null +++ b/fastly/products/ddos_protection/api_test.go @@ -0,0 +1,97 @@ +package ddos_protection_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/ddos_protection" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" + + "github.com/stretchr/testify/require" +) + +var serviceID = fastly.TestDeliveryServiceID + +func TestUpdateConfigurationMissingMode(t *testing.T) { + t.Parallel() + + _, err := tp.UpdateConfiguration(nil, serviceID, &tp.ConfigureInput{Mode: ""}) + + require.ErrorIs(t, err, tp.ErrMissingMode) +} + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + Phase: "default", + OpFn: tp.GetConfiguration, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "log", *output.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + ip.NewUpdateConfigurationTest(&ip.UpdateConfigurationTestInput[*tp.ConfigureInput, *tp.ConfigureOutput]{ + OpFn: tp.UpdateConfiguration, + Input: &tp.ConfigureInput{Mode: "block"}, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "block", *output.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + Phase: "after update", + OpFn: tp.GetConfiguration, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) + require.Equalf(t, "block", *output.Configuration.Mode, "test '%s'", tc.Name) + }, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablementAndConfiguration(t *testing.T) { + fastly.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..d329f57e7 --- /dev/null +++ b/fastly/products/domain_inspector/api.go @@ -0,0 +1,38 @@ +package domain_inspector + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "domain_inspector" + +// Get gets the status of the Domain Inspector product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Domain Inspector product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Domain Inspector product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..2feb9c4f1 --- /dev/null +++ b/fastly/products/domain_inspector/api_test.go @@ -0,0 +1,57 @@ +package domain_inspector_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/domain_inspector" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..91eb2ee48 --- /dev/null +++ b/fastly/products/fanout/api.go @@ -0,0 +1,38 @@ +package fanout + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "fanout" + +// Get gets the status of the Fanout product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Fanout product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Fanout product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..ca485fd0a --- /dev/null +++ b/fastly/products/fanout/api_test.go @@ -0,0 +1,57 @@ +package fanout_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/fanout" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestComputeServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..6727a5d31 --- /dev/null +++ b/fastly/products/image_optimizer/api.go @@ -0,0 +1,38 @@ +package image_optimizer + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "image_optimizer" + +// Get gets the status of the Image Optimizer product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Image Optimizer product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Image Optimizer product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..3b09015d0 --- /dev/null +++ b/fastly/products/image_optimizer/api_test.go @@ -0,0 +1,57 @@ +package image_optimizer_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/image_optimizer" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..19e51f44f --- /dev/null +++ b/fastly/products/log_explorer_insights/api.go @@ -0,0 +1,38 @@ +package log_explorer_insights + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +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) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + 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) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + 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 ip.Delete(&ip.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..70b719f70 --- /dev/null +++ b/fastly/products/log_explorer_insights/api_test.go @@ -0,0 +1,57 @@ +package log_explorer_insights_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/log_explorer_insights" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..b40304e68 --- /dev/null +++ b/fastly/products/ngwaf/api.go @@ -0,0 +1,88 @@ +package ngwaf + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +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 { + fp.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) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + 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) (*fp.EnableOutput, error) { + if i.WorkspaceID == "" { + return nil, ErrMissingWorkspaceID + } + + return ip.Put(&ip.PutInput[EnableInput, fp.EnableOutput]{ + 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 ip.Delete(&ip.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 ip.Get(&ip.GetInput[ConfigureOutput]{ + 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 ip.Patch(&ip.PatchInput[ConfigureInput, ConfigureOutput]{ + 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..ed426fbeb --- /dev/null +++ b/fastly/products/ngwaf/api_test.go @@ -0,0 +1,98 @@ +package ngwaf_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/ngwaf" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" + + "github.com/stretchr/testify/require" +) + +var serviceID = fastly.TestDeliveryServiceID + +func TestEnableMissingWorkspaceID(t *testing.T) { + t.Parallel() + + _, err := tp.Enable(nil, serviceID, &tp.EnableInput{WorkspaceID: ""}) + + require.ErrorIs(t, err, tp.ErrMissingWorkspaceID) +} + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*tp.EnableInput, *fp.EnableOutput]{ + OpWithInputFn: tp.Enable, + Input: &tp.EnableInput{WorkspaceID: fastly.TestNGWAFWorkspaceID}, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + Phase: "default", + OpFn: tp.GetConfiguration, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "100", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + ip.NewUpdateConfigurationTest(&ip.UpdateConfigurationTestInput[*tp.ConfigureInput, *tp.ConfigureOutput]{ + OpFn: tp.UpdateConfiguration, + Input: &tp.ConfigureInput{TrafficRamp: "45"}, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "45", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + Phase: "after update", + OpFn: tp.GetConfiguration, + ProductID: tp.ProductID, + ServiceID: serviceID, + CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + require.NotNilf(t, output.Configuration.TrafficRamp, "test '%s'", tc.Name) + require.Equalf(t, "45", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) + }, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablementAndConfiguration(t *testing.T) { + fastly.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/products/ngwaf/fixtures/disable.yaml b/fastly/products/ngwaf/fixtures/disable.yaml new file mode 100644 index 000000000..9e7f5c007 --- /dev/null +++ b/fastly/products/ngwaf/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/ngwaf/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: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-klot8100133-CHI, cache-ewr-kewr1740067-EWR + X-Timer: + - 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..a4e158973 --- /dev/null +++ b/fastly/products/origin_inspector/api.go @@ -0,0 +1,38 @@ +package origin_inspector + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "origin_inspector" + +// Get gets the status of the Origin Inspector product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the Origin Inspector product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the Origin Inspector product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..9ed5d323e --- /dev/null +++ b/fastly/products/origin_inspector/api_test.go @@ -0,0 +1,57 @@ +package origin_inspector_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/origin_inspector" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..01716f36c --- /dev/null +++ b/fastly/products/websockets/api.go @@ -0,0 +1,38 @@ +package websockets + +import ( + "github.com/fastly/go-fastly/v9/fastly" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +const ProductID = "websockets" + +// Get gets the status of the WebSockets product on the service. +func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Get(&ip.GetInput[fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Enable enables the WebSockets product on the service. +func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { + return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ + Client: c, + ProductID: ProductID, + ServiceID: serviceID, + }) +} + +// Disable disables the WebSockets product on the service. +func Disable(c *fastly.Client, serviceID string) error { + return ip.Delete(&ip.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..966194374 --- /dev/null +++ b/fastly/products/websockets/api_test.go @@ -0,0 +1,57 @@ +package websockets_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + // tp is 'this product' package + tp "github.com/fastly/go-fastly/v9/fastly/products/websockets" + // fp is 'fastly products' package + fp "github.com/fastly/go-fastly/v9/fastly/products" + // ip is 'internal products' package + ip "github.com/fastly/go-fastly/v9/internal/products" +) + +var serviceID = fastly.TestDeliveryServiceID + +var functionalTests = []*fastly.FunctionalTest{ + ip.NewDisableTest(&ip.DisableTestInput{ + Phase: "ensure disabled before testing", + OpFn: tp.Disable, + ServiceID: serviceID, + IgnoreFailure: true, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "before enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), + ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ + OpNoInputFn: tp.Enable, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after enablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + }), + ip.NewDisableTest(&ip.DisableTestInput{ + OpFn: tp.Disable, + ServiceID: serviceID, + }), + ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + Phase: "after disablement", + OpFn: tp.Get, + ProductID: tp.ProductID, + ServiceID: serviceID, + ExpectFailure: true, + }), +} + +func TestEnablement(t *testing.T) { + fastly.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..85c36badb 100644 --- a/go.mod +++ b/go.mod @@ -9,16 +9,20 @@ require ( github.com/mitchellh/mapstructure v1.4.3 github.com/peterhellberg/link v1.1.0 golang.org/x/crypto v0.31.0 + github.com/stretchr/testify v1.10.0 golang.org/x/tools v0.15.0 honnef.co/go/tools v0.3.3 ) 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/products/api_base.go b/internal/products/api_base.go new file mode 100644 index 000000000..a2e5ca041 --- /dev/null +++ b/internal/products/api_base.go @@ -0,0 +1,6 @@ +package products + +// NullInput is used to indicate to the generic FunctionalTest +// constructors that the operation being tested does not accept an +// Input struct +type NullInput struct{} diff --git a/internal/products/api_delete.go b/internal/products/api_delete.go new file mode 100644 index 000000000..96b54be7f --- /dev/null +++ b/internal/products/api_delete.go @@ -0,0 +1,32 @@ +package products + +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/products/api_get.go b/internal/products/api_get.go new file mode 100644 index 000000000..f231db13d --- /dev/null +++ b/internal/products/api_get.go @@ -0,0 +1,45 @@ +package products + +import "github.com/fastly/go-fastly/v9/fastly" + +// GetInput specifies the information needed for the Get() +// function to perform the operation. +// +// Because Get operations produce output, this struct has a type +// parameter used to specify the type of the output; the parameter is +// not used within this structure, but specifying it at this level +// makes type inference simpler when the caller invokes the Get() +// function. +type GetInput[O any] struct { + Client *fastly.Client + ProductID string + ServiceID string + URLComponents []string +} + +// Get implements a product-specific 'get' operation. +// +// This function requires the same type parameter as the GetInput +// struct, and that type is used to construct, populate, and return +// the output present in the response body. +func Get[O any](i *GetInput[O]) (*O, error) { + var err error + if i.ServiceID == "" { + return nil, fastly.ErrMissingServiceID + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.GetJSON(path, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var h *O + if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { + return nil, err + } + + return h, nil +} diff --git a/internal/products/api_patch.go b/internal/products/api_patch.go new file mode 100644 index 000000000..281d3282f --- /dev/null +++ b/internal/products/api_patch.go @@ -0,0 +1,48 @@ +package products + +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 and produce output, this struct +// has two type parameters used to specify the types of the input and +// output; the output parameter is not used within this structure, but +// specifying it at this level makes type inference simpler when the +// caller invokes the Patch() function. +type PatchInput[I, O 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 parameters as the PatchInput +// struct; the input type parameter is used to marshal the input data +// into the request body (encoded as JSON), and the output type +// parameter is used to construct, populate, and return the output +// present in the response body. +func Patch[I, O any](i *PatchInput[I, O]) (*O, error) { + var err error + if i.ServiceID == "" { + return nil, fastly.ErrMissingServiceID + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.PatchJSON(path, i.Input, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var h *O + if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { + return nil, err + } + + return h, nil +} diff --git a/internal/products/api_put.go b/internal/products/api_put.go new file mode 100644 index 000000000..c22b79d85 --- /dev/null +++ b/internal/products/api_put.go @@ -0,0 +1,48 @@ +package products + +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 and produce output, this struct +// has two type parameters used to specify the types of the input and +// output; the output parameter is not used within this structure, but +// specifying it at this level makes type inference simpler when the +// caller invokes the Put() function. +type PutInput[I, O 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 parameters as the PutInput +// struct; the input type parameter is used to marshal the input data +// into the request body (encoded as JSON), and the output type +// parameter is used to construct, populate, and return the output +// present in the response body. +func Put[I, O any](i *PutInput[I, O]) (*O, error) { + var err error + if i.ServiceID == "" { + return nil, fastly.ErrMissingServiceID + } + + path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) + + resp, err := i.Client.PutJSON(path, i.Input, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var h *O + if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { + return nil, err + } + + return h, nil +} diff --git a/internal/products/doc.go b/internal/products/doc.go new file mode 100644 index 000000000..38bf28bb7 --- /dev/null +++ b/internal/products/doc.go @@ -0,0 +1,5 @@ +// Package products 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 products diff --git a/internal/products/functional_test_disable.go b/internal/products/functional_test_disable.go new file mode 100644 index 000000000..e91c302c2 --- /dev/null +++ b/internal/products/functional_test_disable.go @@ -0,0 +1,58 @@ +package products + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" +) + +// 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) *fastly.FunctionalTest { + r := fastly.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, _ *fastly.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/products/functional_test_enable.go b/internal/products/functional_test_enable.go new file mode 100644 index 000000000..a770a64b8 --- /dev/null +++ b/internal/products/functional_test_enable.go @@ -0,0 +1,106 @@ +package products + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" +) + +// 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[I any, O ProductOutput] 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, *fastly.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[I any, O ProductOutput](i *EnableTestInput[I, O]) *fastly.FunctionalTest { + r := fastly.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 *fastly.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 *fastly.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/products/functional_test_get.go b/internal/products/functional_test_get.go new file mode 100644 index 000000000..676e304d1 --- /dev/null +++ b/internal/products/functional_test_get.go @@ -0,0 +1,95 @@ +package products + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "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, *fastly.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]) *fastly.FunctionalTest { + r := fastly.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 *fastly.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/products/functional_test_get_configuration.go b/internal/products/functional_test_get_configuration.go new file mode 100644 index 000000000..e1b49af0f --- /dev/null +++ b/internal/products/functional_test_get_configuration.go @@ -0,0 +1,80 @@ +package products + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" +) + +// 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, *fastly.FunctionalTest, O) +} + +// NewGetConfigurationTest constructs a FunctionalTest object as +// specified by its input. +func NewGetConfigurationTest[O ProductOutput](i *GetConfigurationTestInput[O]) *fastly.FunctionalTest { + r := fastly.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 *fastly.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/products/functional_test_update_configuration.go b/internal/products/functional_test_update_configuration.go new file mode 100644 index 000000000..e01510d32 --- /dev/null +++ b/internal/products/functional_test_update_configuration.go @@ -0,0 +1,91 @@ +package products + +import ( + "strings" + "testing" + + "github.com/fastly/go-fastly/v9/fastly" +) + +// 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[I any, O ProductOutput] 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, *fastly.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[I any, O ProductOutput](i *UpdateConfigurationTestInput[I, O]) *fastly.FunctionalTest { + r := fastly.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 *fastly.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/products/functional_test_utils.go b/internal/products/functional_test_utils.go new file mode 100644 index 000000000..d444b139d --- /dev/null +++ b/internal/products/functional_test_utils.go @@ -0,0 +1,23 @@ +package products + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + "github.com/stretchr/testify/require" +) + +// validateOutput provides common validation for all responses to +// product-specific API operations. +// +// All of these 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[O ProductOutput](t *testing.T, tc *fastly.FunctionalTest, o O, 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/products/products_test.go b/internal/products/products_test.go new file mode 100644 index 000000000..3a12af737 --- /dev/null +++ b/internal/products/products_test.go @@ -0,0 +1,49 @@ +package products_test + +import ( + "testing" + + "github.com/fastly/go-fastly/v9/fastly" + p "github.com/fastly/go-fastly/v9/internal/products" + "github.com/stretchr/testify/require" +) + +func TestDeleteMissingServiceID(t *testing.T) { + t.Parallel() + + err := p.Delete(&p.DeleteInput{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestGetMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := p.Get(&p.GetInput[fastly.ProductEnablement]{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestPatchMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := p.Patch(&p.PatchInput[p.NullInput, fastly.ProductEnablement]{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} + +func TestPutMissingServiceID(t *testing.T) { + t.Parallel() + + _, err := p.Put(&p.PutInput[p.NullInput, fastly.ProductEnablement]{ + ServiceID: "", + }) + + require.ErrorIs(t, err, fastly.ErrMissingServiceID) +} diff --git a/internal/products/types.go b/internal/products/types.go new file mode 100644 index 000000000..ab1ab6d1c --- /dev/null +++ b/internal/products/types.go @@ -0,0 +1,15 @@ +package products + +// ProductOutput is an interface used to constrain the 'O' type +// parameter of the FunctionalTest constructors in this package. Use +// of this interface allows those 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. +// +// This interface matches the methods of the EnableOutput and +// ConfigureOutput structs in the fastly/products package. +type ProductOutput interface { + ProductID() *string + ServiceID() *string +} diff --git a/internal/products/utils.go b/internal/products/utils.go new file mode 100644 index 000000000..d62cd3656 --- /dev/null +++ b/internal/products/utils.go @@ -0,0 +1,17 @@ +package products + +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/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 " ===== " From a0747181e2b2360098214d4e30904c9ee6fc2b24 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Sat, 7 Dec 2024 11:58:46 -0500 Subject: [PATCH 2/8] Move image_optimizer_default_settings_test to its own package to avoid an import cycle. --- .../disable_product.yaml | 45 ------ .../fixtures/disable_product.yaml | 52 +++++++ .../fixtures}/enable_product.yaml | 34 ++-- .../fixtures}/final_reset.yaml | 22 +-- .../fixtures}/incorrect_fetch.yaml | 22 +-- .../fixtures}/original_fetch.yaml | 18 +-- .../fixtures}/set_full.yaml | 22 +-- .../fixtures}/set_jpeg_type/auto.yaml | 22 +-- .../fixtures}/set_jpeg_type/baseline.yaml | 22 +-- .../fixtures}/set_jpeg_type/progressive.yaml | 22 +-- .../fixtures}/set_resize_filter/bicubic.yaml | 22 +-- .../fixtures}/set_resize_filter/bilinear.yaml | 22 +-- .../fixtures}/set_resize_filter/lanczos2.yaml | 22 +-- .../fixtures}/set_resize_filter/lanczos3.yaml | 22 +-- .../fixtures}/set_resize_filter/nearest.yaml | 22 +-- .../fixtures}/update_1_get.yaml | 18 +-- .../fixtures}/update_1_patch.yaml | 22 +-- .../fixtures}/update_2_get.yaml | 18 +-- .../fixtures}/update_2_patch.yaml | 22 +-- .../fixtures}/version.yaml | 22 +-- .../image_optimizer_default_settings_test.go | 145 +++++++++--------- 21 files changed, 320 insertions(+), 318 deletions(-) delete mode 100644 fastly/fixtures/image_optimizer_default_settings/disable_product.yaml create mode 100644 fastly/image_optimizer_default_settings/fixtures/disable_product.yaml rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/enable_product.yaml (52%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/final_reset.yaml (73%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/incorrect_fetch.yaml (73%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/original_fetch.yaml (69%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_full.yaml (73%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_jpeg_type/auto.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_jpeg_type/baseline.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_jpeg_type/progressive.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_resize_filter/bicubic.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_resize_filter/bilinear.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_resize_filter/lanczos2.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_resize_filter/lanczos3.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/set_resize_filter/nearest.yaml (71%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/update_1_get.yaml (69%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/update_1_patch.yaml (72%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/update_2_get.yaml (69%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/update_2_patch.yaml (72%) rename fastly/{fixtures/image_optimizer_default_settings => image_optimizer_default_settings/fixtures}/version.yaml (65%) rename fastly/{ => image_optimizer_default_settings}/image_optimizer_default_settings_test.go (54%) diff --git a/fastly/fixtures/image_optimizer_default_settings/disable_product.yaml b/fastly/fixtures/image_optimizer_default_settings/disable_product.yaml deleted file mode 100644 index a7c3acd2f..000000000 --- a/fastly/fixtures/image_optimizer_default_settings/disable_product.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: "" - 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 - method: DELETE - response: - body: "" - headers: - Accept-Ranges: - - bytes - Cache-Control: - - no-store - Content-Type: - - application/json - Date: - - Tue, 14 May 2024 16:16:36 GMT - Pragma: - - no-cache - Server: - - control-gateway - Status: - - 204 No Content - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Accept-Encoding - Via: - - 1.1 varnish - X-Cache: - - MISS - X-Cache-Hits: - - "0" - X-Served-By: - - cache-bfi-krnt7300110-BFI - X-Timer: - - S1715703395.638107,VS0,VE1368 - status: 204 No Content - code: 204 - duration: "" 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) } } From 23e9a6e2426b98a97e9e9fc218e7bd248d8a72d2 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Tue, 10 Dec 2024 11:37:56 -0500 Subject: [PATCH 3/8] ConfigureOutputNested struct does not need to be exported. --- fastly/products/ddos_protection/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastly/products/ddos_protection/api.go b/fastly/products/ddos_protection/api.go index 036dc83de..8ed97e6d1 100644 --- a/fastly/products/ddos_protection/api.go +++ b/fastly/products/ddos_protection/api.go @@ -21,10 +21,10 @@ type ConfigureInput struct { type ConfigureOutput struct { fp.ConfigureOutput `mapstructure:",squash"` - Configuration *ConfigureOutputNested `mapstructure:"configuration"` + Configuration *configureOutputNested `mapstructure:"configuration"` } -type ConfigureOutputNested struct { +type configureOutputNested struct { Mode *string `mapstructure:"mode"` } From de962ad74029230ddc2efc5405ebe6b2a7c18e34 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Thu, 12 Dec 2024 14:04:32 -0500 Subject: [PATCH 4/8] Apply review feedback. --- internal/products/api_base.go | 6 ------ internal/products/types.go | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 internal/products/api_base.go diff --git a/internal/products/api_base.go b/internal/products/api_base.go deleted file mode 100644 index a2e5ca041..000000000 --- a/internal/products/api_base.go +++ /dev/null @@ -1,6 +0,0 @@ -package products - -// NullInput is used to indicate to the generic FunctionalTest -// constructors that the operation being tested does not accept an -// Input struct -type NullInput struct{} diff --git a/internal/products/types.go b/internal/products/types.go index ab1ab6d1c..688995482 100644 --- a/internal/products/types.go +++ b/internal/products/types.go @@ -13,3 +13,8 @@ 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{} From 154d5debb69093c3588db144e165808eb6ff82c3 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Thu, 12 Dec 2024 15:58:23 -0500 Subject: [PATCH 5/8] Apply some review feedback: use ProductOutput constraint everywhere. --- fastly/products/api_output.go | 4 ++-- go.mod | 2 +- internal/products/api_get.go | 4 ++-- internal/products/api_patch.go | 4 ++-- internal/products/api_put.go | 4 ++-- internal/products/products_test.go | 6 +++--- internal/products/types.go | 13 +++++++++++++ 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/fastly/products/api_output.go b/fastly/products/api_output.go index d8c462665..4e07bac5e 100644 --- a/fastly/products/api_output.go +++ b/fastly/products/api_output.go @@ -18,7 +18,7 @@ type enableOutputNested struct { // 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 { +func (o EnableOutput) ProductID() *string { return o.Product.ID } @@ -27,7 +27,7 @@ func (o *EnableOutput) ProductID() *string { // 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 { +func (o EnableOutput) ServiceID() *string { return o.Service.ID } diff --git a/go.mod b/go.mod index 85c36badb..8846fb02e 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/mitchellh/mapstructure v1.4.3 github.com/peterhellberg/link v1.1.0 - golang.org/x/crypto v0.31.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 ) diff --git a/internal/products/api_get.go b/internal/products/api_get.go index f231db13d..f8f8e735e 100644 --- a/internal/products/api_get.go +++ b/internal/products/api_get.go @@ -10,7 +10,7 @@ import "github.com/fastly/go-fastly/v9/fastly" // not used within this structure, but specifying it at this level // makes type inference simpler when the caller invokes the Get() // function. -type GetInput[O any] struct { +type GetInput[O ProductOutput] struct { Client *fastly.Client ProductID string ServiceID string @@ -22,7 +22,7 @@ type GetInput[O any] struct { // This function requires the same type parameter as the GetInput // struct, and that type is used to construct, populate, and return // the output present in the response body. -func Get[O any](i *GetInput[O]) (*O, error) { +func Get[O ProductOutput](i *GetInput[O]) (*O, error) { var err error if i.ServiceID == "" { return nil, fastly.ErrMissingServiceID diff --git a/internal/products/api_patch.go b/internal/products/api_patch.go index 281d3282f..af3c50d02 100644 --- a/internal/products/api_patch.go +++ b/internal/products/api_patch.go @@ -10,7 +10,7 @@ import "github.com/fastly/go-fastly/v9/fastly" // output; the output parameter is not used within this structure, but // specifying it at this level makes type inference simpler when the // caller invokes the Patch() function. -type PatchInput[I, O any] struct { +type PatchInput[I any, O ProductOutput] struct { Client *fastly.Client ProductID string ServiceID string @@ -25,7 +25,7 @@ type PatchInput[I, O any] struct { // into the request body (encoded as JSON), and the output type // parameter is used to construct, populate, and return the output // present in the response body. -func Patch[I, O any](i *PatchInput[I, O]) (*O, error) { +func Patch[I any, O ProductOutput](i *PatchInput[I, O]) (*O, error) { var err error if i.ServiceID == "" { return nil, fastly.ErrMissingServiceID diff --git a/internal/products/api_put.go b/internal/products/api_put.go index c22b79d85..42ab2aa96 100644 --- a/internal/products/api_put.go +++ b/internal/products/api_put.go @@ -10,7 +10,7 @@ import "github.com/fastly/go-fastly/v9/fastly" // output; the output parameter is not used within this structure, but // specifying it at this level makes type inference simpler when the // caller invokes the Put() function. -type PutInput[I, O any] struct { +type PutInput[I any, O ProductOutput] struct { Client *fastly.Client ProductID string ServiceID string @@ -25,7 +25,7 @@ type PutInput[I, O any] struct { // into the request body (encoded as JSON), and the output type // parameter is used to construct, populate, and return the output // present in the response body. -func Put[I, O any](i *PutInput[I, O]) (*O, error) { +func Put[I any, O ProductOutput](i *PutInput[I, O]) (*O, error) { var err error if i.ServiceID == "" { return nil, fastly.ErrMissingServiceID diff --git a/internal/products/products_test.go b/internal/products/products_test.go index 3a12af737..ce5365295 100644 --- a/internal/products/products_test.go +++ b/internal/products/products_test.go @@ -21,7 +21,7 @@ func TestDeleteMissingServiceID(t *testing.T) { func TestGetMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Get(&p.GetInput[fastly.ProductEnablement]{ + _, err := p.Get(&p.GetInput[p.NullOutput]{ ServiceID: "", }) @@ -31,7 +31,7 @@ func TestGetMissingServiceID(t *testing.T) { func TestPatchMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Patch(&p.PatchInput[p.NullInput, fastly.ProductEnablement]{ + _, err := p.Patch(&p.PatchInput[p.NullInput, p.NullOutput]{ ServiceID: "", }) @@ -41,7 +41,7 @@ func TestPatchMissingServiceID(t *testing.T) { func TestPutMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Put(&p.PutInput[p.NullInput, fastly.ProductEnablement]{ + _, err := p.Put(&p.PutInput[p.NullInput, p.NullOutput]{ ServiceID: "", }) diff --git a/internal/products/types.go b/internal/products/types.go index 688995482..be6959142 100644 --- a/internal/products/types.go +++ b/internal/products/types.go @@ -18,3 +18,16 @@ type ProductOutput interface { // 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 +} From 449ec7b2667852d1184adce5198e47c43dbf1a39 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Fri, 13 Dec 2024 17:32:13 -0500 Subject: [PATCH 6/8] Apply review feedback: 1. Rename internal/products to internal/productcore 2. Eliminate import aliases 3. Eliminate type parameters on structs that don't use them 4. Use pointer receivers for methods in ProductOutput interface --- fastly/products/api_output.go | 4 +- fastly/products/bot_management/api.go | 16 ++-- fastly/products/bot_management/api_test.go | 41 +++++---- fastly/products/brotli_compression/api.go | 16 ++-- .../products/brotli_compression/api_test.go | 41 +++++---- fastly/products/ddos_protection/api.go | 24 +++--- fastly/products/ddos_protection/api_test.go | 83 +++++++++---------- fastly/products/domain_inspector/api.go | 16 ++-- fastly/products/domain_inspector/api_test.go | 41 +++++---- fastly/products/fanout/api.go | 16 ++-- fastly/products/fanout/api_test.go | 41 +++++---- fastly/products/image_optimizer/api.go | 16 ++-- fastly/products/image_optimizer/api_test.go | 41 +++++---- fastly/products/log_explorer_insights/api.go | 16 ++-- .../log_explorer_insights/api_test.go | 41 +++++---- fastly/products/ngwaf/api.go | 24 +++--- fastly/products/ngwaf/api_test.go | 73 ++++++++-------- fastly/products/origin_inspector/api.go | 16 ++-- fastly/products/origin_inspector/api_test.go | 41 +++++---- fastly/products/websockets/api.go | 16 ++-- fastly/products/websockets/api_test.go | 41 +++++---- .../{products => productcore}/api_delete.go | 2 +- internal/productcore/api_get.go | 36 ++++++++ internal/productcore/api_patch.go | 44 ++++++++++ internal/productcore/api_put.go | 44 ++++++++++ internal/{products => productcore}/doc.go | 4 +- .../functional_test_disable.go | 2 +- .../functional_test_enable.go | 2 +- .../functional_test_get.go | 2 +- .../functional_test_get_configuration.go | 2 +- .../functional_test_update_configuration.go | 2 +- .../functional_test_utils.go | 12 +-- .../productcore_test.go} | 12 +-- internal/{products => productcore}/types.go | 17 ++-- internal/{products => productcore}/utils.go | 2 +- internal/products/api_get.go | 45 ---------- internal/products/api_patch.go | 48 ----------- internal/products/api_put.go | 48 ----------- 38 files changed, 461 insertions(+), 527 deletions(-) rename internal/{products => productcore}/api_delete.go (97%) create mode 100644 internal/productcore/api_get.go create mode 100644 internal/productcore/api_patch.go create mode 100644 internal/productcore/api_put.go rename internal/{products => productcore}/doc.go (66%) rename internal/{products => productcore}/functional_test_disable.go (98%) rename internal/{products => productcore}/functional_test_enable.go (99%) rename internal/{products => productcore}/functional_test_get.go (99%) rename internal/{products => productcore}/functional_test_get_configuration.go (99%) rename internal/{products => productcore}/functional_test_update_configuration.go (99%) rename internal/{products => productcore}/functional_test_utils.go (59%) rename internal/{products/products_test.go => productcore/productcore_test.go} (59%) rename internal/{products => productcore}/types.go (55%) rename internal/{products => productcore}/utils.go (94%) delete mode 100644 internal/products/api_get.go delete mode 100644 internal/products/api_patch.go delete mode 100644 internal/products/api_put.go diff --git a/fastly/products/api_output.go b/fastly/products/api_output.go index 4e07bac5e..d8c462665 100644 --- a/fastly/products/api_output.go +++ b/fastly/products/api_output.go @@ -18,7 +18,7 @@ type enableOutputNested struct { // 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 { +func (o *EnableOutput) ProductID() *string { return o.Product.ID } @@ -27,7 +27,7 @@ func (o EnableOutput) ProductID() *string { // 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 { +func (o *EnableOutput) ServiceID() *string { return o.Service.ID } diff --git a/fastly/products/bot_management/api.go b/fastly/products/bot_management/api.go index 47a528bcb..715ee291b 100644 --- a/fastly/products/bot_management/api.go +++ b/fastly/products/bot_management/api.go @@ -2,17 +2,15 @@ package bot_management import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Bot Management product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Bot Management product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index d248875e0..5b8791da5 100644 --- a/fastly/products/bot_management/api_test.go +++ b/fastly/products/bot_management/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/bot_management" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: bot_management.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: bot_management.Enable, + ProductID: bot_management.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: bot_management.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: bot_management.Get, + ProductID: bot_management.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/brotli_compression/api.go b/fastly/products/brotli_compression/api.go index 5abc6e1bf..f2747c0f7 100644 --- a/fastly/products/brotli_compression/api.go +++ b/fastly/products/brotli_compression/api.go @@ -2,17 +2,15 @@ package brotli_compression import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Brotli Compression product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Brotli Compression product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index e9083620d..67ba8f95a 100644 --- a/fastly/products/brotli_compression/api_test.go +++ b/fastly/products/brotli_compression/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/brotli_compression" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: brotli_compression.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: brotli_compression.Enable, + ProductID: brotli_compression.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: brotli_compression.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: brotli_compression.Get, + ProductID: brotli_compression.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/ddos_protection/api.go b/fastly/products/ddos_protection/api.go index 8ed97e6d1..a42c5ae42 100644 --- a/fastly/products/ddos_protection/api.go +++ b/fastly/products/ddos_protection/api.go @@ -2,10 +2,8 @@ package ddos_protection import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" ) const ProductID = "ddos_protection" @@ -20,8 +18,8 @@ type ConfigureInput struct { } type ConfigureOutput struct { - fp.ConfigureOutput `mapstructure:",squash"` - Configuration *configureOutputNested `mapstructure:"configuration"` + products.ConfigureOutput `mapstructure:",squash"` + Configuration *configureOutputNested `mapstructure:"configuration"` } type configureOutputNested struct { @@ -29,8 +27,8 @@ type configureOutputNested struct { } // Get gets the status of the DDoS Protection product on the service. -func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -38,8 +36,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the DDoS Protection product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -48,7 +46,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the DDoS Protection product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + return productcore.Delete(&productcore.DeleteInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -57,7 +55,7 @@ func Disable(c *fastly.Client, serviceID string) error { // GetConfiguration gets the configuration of the DDoS Protection product on the service. func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, error) { - return ip.Get(&ip.GetInput[ConfigureOutput]{ + return productcore.Get[*ConfigureOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -71,7 +69,7 @@ func UpdateConfiguration(c *fastly.Client, serviceID string, i *ConfigureInput) return nil, ErrMissingMode } - return ip.Patch(&ip.PatchInput[ConfigureInput, ConfigureOutput]{ + return productcore.Patch[*ConfigureInput, *ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/ddos_protection/api_test.go b/fastly/products/ddos_protection/api_test.go index a3dc34b10..8cf1bda67 100644 --- a/fastly/products/ddos_protection/api_test.go +++ b/fastly/products/ddos_protection/api_test.go @@ -4,12 +4,9 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/ddos_protection" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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/stretchr/testify/require" ) @@ -19,74 +16,74 @@ var serviceID = fastly.TestDeliveryServiceID func TestUpdateConfigurationMissingMode(t *testing.T) { t.Parallel() - _, err := tp.UpdateConfiguration(nil, serviceID, &tp.ConfigureInput{Mode: ""}) + _, err := ddos_protection.UpdateConfiguration(nil, serviceID, &ddos_protection.ConfigureInput{Mode: ""}) - require.ErrorIs(t, err, tp.ErrMissingMode) + require.ErrorIs(t, err, ddos_protection.ErrMissingMode) } var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: ddos_protection.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: ddos_protection.Enable, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, }), - ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ddos_protection.ConfigureOutput]{ Phase: "default", - OpFn: tp.GetConfiguration, - ProductID: tp.ProductID, + OpFn: ddos_protection.GetConfiguration, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { - require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) - require.Equalf(t, "log", *output.Configuration.Mode, "test '%s'", tc.Name) + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewUpdateConfigurationTest(&ip.UpdateConfigurationTestInput[*tp.ConfigureInput, *tp.ConfigureOutput]{ - OpFn: tp.UpdateConfiguration, - Input: &tp.ConfigureInput{Mode: "block"}, - ProductID: tp.ProductID, + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ddos_protection.ConfigureInput, *ddos_protection.ConfigureOutput]{ + OpFn: ddos_protection.UpdateConfiguration, + Input: &ddos_protection.ConfigureInput{Mode: "block"}, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { - require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) - require.Equalf(t, "block", *output.Configuration.Mode, "test '%s'", tc.Name) + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ddos_protection.ConfigureOutput]{ Phase: "after update", - OpFn: tp.GetConfiguration, - ProductID: tp.ProductID, + OpFn: ddos_protection.GetConfiguration, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { - require.NotNilf(t, output.Configuration.Mode, "test '%s'", tc.Name) - require.Equalf(t, "block", *output.Configuration.Mode, "test '%s'", tc.Name) + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: ddos_protection.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ddos_protection.Get, + ProductID: ddos_protection.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/domain_inspector/api.go b/fastly/products/domain_inspector/api.go index d329f57e7..12fba953d 100644 --- a/fastly/products/domain_inspector/api.go +++ b/fastly/products/domain_inspector/api.go @@ -2,17 +2,15 @@ package domain_inspector import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Domain Inspector product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Domain Inspector product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index 2feb9c4f1..f57033e7f 100644 --- a/fastly/products/domain_inspector/api_test.go +++ b/fastly/products/domain_inspector/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/domain_inspector" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: domain_inspector.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: domain_inspector.Enable, + ProductID: domain_inspector.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: domain_inspector.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: domain_inspector.Get, + ProductID: domain_inspector.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/fanout/api.go b/fastly/products/fanout/api.go index 91eb2ee48..c6529b667 100644 --- a/fastly/products/fanout/api.go +++ b/fastly/products/fanout/api.go @@ -2,17 +2,15 @@ package fanout import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Fanout product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Fanout product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index ca485fd0a..63389da85 100644 --- a/fastly/products/fanout/api_test.go +++ b/fastly/products/fanout/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/fanout" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestComputeServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: fanout.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: fanout.Get, + ProductID: fanout.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: fanout.Enable, + ProductID: fanout.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: fanout.Get, + ProductID: fanout.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: fanout.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: fanout.Get, + ProductID: fanout.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/image_optimizer/api.go b/fastly/products/image_optimizer/api.go index 6727a5d31..5e9523d23 100644 --- a/fastly/products/image_optimizer/api.go +++ b/fastly/products/image_optimizer/api.go @@ -2,17 +2,15 @@ package image_optimizer import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Image Optimizer product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Image Optimizer product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index 3b09015d0..8677a026a 100644 --- a/fastly/products/image_optimizer/api_test.go +++ b/fastly/products/image_optimizer/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/image_optimizer" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: image_optimizer.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: image_optimizer.Enable, + ProductID: image_optimizer.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: image_optimizer.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: image_optimizer.Get, + ProductID: image_optimizer.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/log_explorer_insights/api.go b/fastly/products/log_explorer_insights/api.go index 19e51f44f..2867330a7 100644 --- a/fastly/products/log_explorer_insights/api.go +++ b/fastly/products/log_explorer_insights/api.go @@ -2,17 +2,15 @@ package log_explorer_insights import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Log Explorer Bot Management Insights product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Log Explorer Bot Management Insights product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index 70b719f70..db96a80b3 100644 --- a/fastly/products/log_explorer_insights/api_test.go +++ b/fastly/products/log_explorer_insights/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/log_explorer_insights" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: log_explorer_insights.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: log_explorer_insights.Enable, + ProductID: log_explorer_insights.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: log_explorer_insights.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: log_explorer_insights.Get, + ProductID: log_explorer_insights.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/ngwaf/api.go b/fastly/products/ngwaf/api.go index b40304e68..8e78eb699 100644 --- a/fastly/products/ngwaf/api.go +++ b/fastly/products/ngwaf/api.go @@ -2,10 +2,8 @@ package ngwaf import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "github.com/fastly/go-fastly/v9/fastly/products" + "github.com/fastly/go-fastly/v9/internal/productcore" ) const ProductID = "ngwaf" @@ -25,8 +23,8 @@ type ConfigureInput struct { } type ConfigureOutput struct { - fp.ConfigureOutput `mapstructure:",squash"` - Configuration *configureOutputNested `mapstructure:"configuration"` + products.ConfigureOutput `mapstructure:",squash"` + Configuration *configureOutputNested `mapstructure:"configuration"` } type configureOutputNested struct { @@ -35,8 +33,8 @@ type configureOutputNested struct { } // Get gets the status of the Next-Gen WAF product on the service. -func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -44,12 +42,12 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Next-Gen WAF product on the service. -func Enable(c *fastly.Client, serviceID string, i *EnableInput) (*fp.EnableOutput, error) { +func Enable(c *fastly.Client, serviceID string, i *EnableInput) (*products.EnableOutput, error) { if i.WorkspaceID == "" { return nil, ErrMissingWorkspaceID } - return ip.Put(&ip.PutInput[EnableInput, fp.EnableOutput]{ + return productcore.Put[*EnableInput, *products.EnableOutput](&productcore.PutInput[*EnableInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -59,7 +57,7 @@ func Enable(c *fastly.Client, serviceID string, i *EnableInput) (*fp.EnableOutpu // Disable disables the Next-Gen WAF product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + return productcore.Delete(&productcore.DeleteInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -68,7 +66,7 @@ func Disable(c *fastly.Client, serviceID string) error { // GetConfiguration gets the configuration of the Next-Gen WAF product on the service. func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, error) { - return ip.Get(&ip.GetInput[ConfigureOutput]{ + return productcore.Get[*ConfigureOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -78,7 +76,7 @@ func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, err // 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 ip.Patch(&ip.PatchInput[ConfigureInput, ConfigureOutput]{ + return productcore.Patch[*ConfigureInput, *ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/ngwaf/api_test.go b/fastly/products/ngwaf/api_test.go index ed426fbeb..162696379 100644 --- a/fastly/products/ngwaf/api_test.go +++ b/fastly/products/ngwaf/api_test.go @@ -4,12 +4,9 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/ngwaf" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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/stretchr/testify/require" ) @@ -19,75 +16,75 @@ var serviceID = fastly.TestDeliveryServiceID func TestEnableMissingWorkspaceID(t *testing.T) { t.Parallel() - _, err := tp.Enable(nil, serviceID, &tp.EnableInput{WorkspaceID: ""}) + _, err := ngwaf.Enable(nil, serviceID, &ngwaf.EnableInput{WorkspaceID: ""}) - require.ErrorIs(t, err, tp.ErrMissingWorkspaceID) + require.ErrorIs(t, err, ngwaf.ErrMissingWorkspaceID) } var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: ngwaf.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*tp.EnableInput, *fp.EnableOutput]{ - OpWithInputFn: tp.Enable, - Input: &tp.EnableInput{WorkspaceID: fastly.TestNGWAFWorkspaceID}, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*ngwaf.EnableInput, *products.EnableOutput]{ + OpWithInputFn: ngwaf.Enable, + Input: &ngwaf.EnableInput{WorkspaceID: fastly.TestNGWAFWorkspaceID}, + ProductID: ngwaf.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, ServiceID: serviceID, }), - ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ngwaf.ConfigureOutput]{ Phase: "default", - OpFn: tp.GetConfiguration, - ProductID: tp.ProductID, + OpFn: ngwaf.GetConfiguration, + ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewUpdateConfigurationTest(&ip.UpdateConfigurationTestInput[*tp.ConfigureInput, *tp.ConfigureOutput]{ - OpFn: tp.UpdateConfiguration, - Input: &tp.ConfigureInput{TrafficRamp: "45"}, - ProductID: tp.ProductID, + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ngwaf.ConfigureInput, *ngwaf.ConfigureOutput]{ + OpFn: ngwaf.UpdateConfiguration, + Input: &ngwaf.ConfigureInput{TrafficRamp: "45"}, + ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewGetConfigurationTest(&ip.GetConfigurationTestInput[*tp.ConfigureOutput]{ + productcore.NewGetConfigurationTest(&productcore.GetConfigurationTestInput[*ngwaf.ConfigureOutput]{ Phase: "after update", - OpFn: tp.GetConfiguration, - ProductID: tp.ProductID, + OpFn: ngwaf.GetConfiguration, + ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *tp.ConfigureOutput) { + CheckOutputFn: func(t *testing.T, tc *fastly.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) }, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: ngwaf.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: ngwaf.Get, + ProductID: ngwaf.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/origin_inspector/api.go b/fastly/products/origin_inspector/api.go index a4e158973..d5d142314 100644 --- a/fastly/products/origin_inspector/api.go +++ b/fastly/products/origin_inspector/api.go @@ -2,17 +2,15 @@ package origin_inspector import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the Origin Inspector product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the Origin Inspector product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index 9ed5d323e..cf0931115 100644 --- a/fastly/products/origin_inspector/api_test.go +++ b/fastly/products/origin_inspector/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/origin_inspector" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: origin_inspector.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: origin_inspector.Enable, + ProductID: origin_inspector.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: origin_inspector.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: origin_inspector.Get, + ProductID: origin_inspector.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/fastly/products/websockets/api.go b/fastly/products/websockets/api.go index 01716f36c..65a866529 100644 --- a/fastly/products/websockets/api.go +++ b/fastly/products/websockets/api.go @@ -2,17 +2,15 @@ package websockets import ( "github.com/fastly/go-fastly/v9/fastly" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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) (*fp.EnableOutput, error) { - return ip.Get(&ip.GetInput[fp.EnableOutput]{ +func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Get[*products.EnableOutput](&productcore.GetInput{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -20,8 +18,8 @@ func Get(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { } // Enable enables the WebSockets product on the service. -func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { - return ip.Put(&ip.PutInput[ip.NullInput, fp.EnableOutput]{ +func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { + return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -30,7 +28,7 @@ func Enable(c *fastly.Client, serviceID string) (*fp.EnableOutput, error) { // Disable disables the WebSockets product on the service. func Disable(c *fastly.Client, serviceID string) error { - return ip.Delete(&ip.DeleteInput{ + 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 index 966194374..68ffc7699 100644 --- a/fastly/products/websockets/api_test.go +++ b/fastly/products/websockets/api_test.go @@ -4,49 +4,46 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - // tp is 'this product' package - tp "github.com/fastly/go-fastly/v9/fastly/products/websockets" - // fp is 'fastly products' package - fp "github.com/fastly/go-fastly/v9/fastly/products" - // ip is 'internal products' package - ip "github.com/fastly/go-fastly/v9/internal/products" + "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" ) var serviceID = fastly.TestDeliveryServiceID var functionalTests = []*fastly.FunctionalTest{ - ip.NewDisableTest(&ip.DisableTestInput{ + productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", - OpFn: tp.Disable, + OpFn: websockets.Disable, ServiceID: serviceID, IgnoreFailure: true, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "before enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: websockets.Get, + ProductID: websockets.ProductID, ServiceID: serviceID, ExpectFailure: true, }), - ip.NewEnableTest(&ip.EnableTestInput[*ip.NullInput, *fp.EnableOutput]{ - OpNoInputFn: tp.Enable, - ProductID: tp.ProductID, + productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + OpNoInputFn: websockets.Enable, + ProductID: websockets.ProductID, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after enablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: websockets.Get, + ProductID: websockets.ProductID, ServiceID: serviceID, }), - ip.NewDisableTest(&ip.DisableTestInput{ - OpFn: tp.Disable, + productcore.NewDisableTest(&productcore.DisableTestInput{ + OpFn: websockets.Disable, ServiceID: serviceID, }), - ip.NewGetTest(&ip.GetTestInput[*fp.EnableOutput]{ + productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{ Phase: "after disablement", - OpFn: tp.Get, - ProductID: tp.ProductID, + OpFn: websockets.Get, + ProductID: websockets.ProductID, ServiceID: serviceID, ExpectFailure: true, }), diff --git a/internal/products/api_delete.go b/internal/productcore/api_delete.go similarity index 97% rename from internal/products/api_delete.go rename to internal/productcore/api_delete.go index 96b54be7f..d73a9b95c 100644 --- a/internal/products/api_delete.go +++ b/internal/productcore/api_delete.go @@ -1,4 +1,4 @@ -package products +package productcore import "github.com/fastly/go-fastly/v9/fastly" diff --git a/internal/productcore/api_get.go b/internal/productcore/api_get.go new file mode 100644 index 000000000..26da17b7e --- /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 +// interface 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..c2a54185e --- /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 +// interface which matches the ProductOutput interface, and that type +// is used to construct, populate, and return the output present in +// the response body. +func Patch[I any, O ProductOutput](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..df0af702f --- /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 +// interface which matches the ProductOutput interface, and that type +// is used to construct, populate, and return the output present in +// the response body. +func Put[I any, O ProductOutput](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/products/doc.go b/internal/productcore/doc.go similarity index 66% rename from internal/products/doc.go rename to internal/productcore/doc.go index 38bf28bb7..423cdaa01 100644 --- a/internal/products/doc.go +++ b/internal/productcore/doc.go @@ -1,5 +1,5 @@ -// Package products provides a group of generic HTTP operation +// 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 products +package productcore diff --git a/internal/products/functional_test_disable.go b/internal/productcore/functional_test_disable.go similarity index 98% rename from internal/products/functional_test_disable.go rename to internal/productcore/functional_test_disable.go index e91c302c2..d58f73e0c 100644 --- a/internal/products/functional_test_disable.go +++ b/internal/productcore/functional_test_disable.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "strings" diff --git a/internal/products/functional_test_enable.go b/internal/productcore/functional_test_enable.go similarity index 99% rename from internal/products/functional_test_enable.go rename to internal/productcore/functional_test_enable.go index a770a64b8..769e92ab9 100644 --- a/internal/products/functional_test_enable.go +++ b/internal/productcore/functional_test_enable.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "strings" diff --git a/internal/products/functional_test_get.go b/internal/productcore/functional_test_get.go similarity index 99% rename from internal/products/functional_test_get.go rename to internal/productcore/functional_test_get.go index 676e304d1..b7fa8fbb8 100644 --- a/internal/products/functional_test_get.go +++ b/internal/productcore/functional_test_get.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "strings" diff --git a/internal/products/functional_test_get_configuration.go b/internal/productcore/functional_test_get_configuration.go similarity index 99% rename from internal/products/functional_test_get_configuration.go rename to internal/productcore/functional_test_get_configuration.go index e1b49af0f..c5be84123 100644 --- a/internal/products/functional_test_get_configuration.go +++ b/internal/productcore/functional_test_get_configuration.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "strings" diff --git a/internal/products/functional_test_update_configuration.go b/internal/productcore/functional_test_update_configuration.go similarity index 99% rename from internal/products/functional_test_update_configuration.go rename to internal/productcore/functional_test_update_configuration.go index e01510d32..912da0ed6 100644 --- a/internal/products/functional_test_update_configuration.go +++ b/internal/productcore/functional_test_update_configuration.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "strings" diff --git a/internal/products/functional_test_utils.go b/internal/productcore/functional_test_utils.go similarity index 59% rename from internal/products/functional_test_utils.go rename to internal/productcore/functional_test_utils.go index d444b139d..56b6216c5 100644 --- a/internal/products/functional_test_utils.go +++ b/internal/productcore/functional_test_utils.go @@ -1,4 +1,4 @@ -package products +package productcore import ( "testing" @@ -10,11 +10,11 @@ import ( // validateOutput provides common validation for all responses to // product-specific API operations. // -// All of these 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[O ProductOutput](t *testing.T, tc *fastly.FunctionalTest, o O, productID, serviceID string) { +// 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 *fastly.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) diff --git a/internal/products/products_test.go b/internal/productcore/productcore_test.go similarity index 59% rename from internal/products/products_test.go rename to internal/productcore/productcore_test.go index ce5365295..69f9f4ae9 100644 --- a/internal/products/products_test.go +++ b/internal/productcore/productcore_test.go @@ -1,17 +1,17 @@ -package products_test +package productcore_test import ( "testing" "github.com/fastly/go-fastly/v9/fastly" - p "github.com/fastly/go-fastly/v9/internal/products" + "github.com/fastly/go-fastly/v9/internal/productcore" "github.com/stretchr/testify/require" ) func TestDeleteMissingServiceID(t *testing.T) { t.Parallel() - err := p.Delete(&p.DeleteInput{ + err := productcore.Delete(&productcore.DeleteInput{ ServiceID: "", }) @@ -21,7 +21,7 @@ func TestDeleteMissingServiceID(t *testing.T) { func TestGetMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Get(&p.GetInput[p.NullOutput]{ + _, err := productcore.Get[*productcore.NullOutput](&productcore.GetInput{ ServiceID: "", }) @@ -31,7 +31,7 @@ func TestGetMissingServiceID(t *testing.T) { func TestPatchMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Patch(&p.PatchInput[p.NullInput, p.NullOutput]{ + _, err := productcore.Patch[*productcore.NullInput, *productcore.NullOutput](&productcore.PatchInput[*productcore.NullInput]{ ServiceID: "", }) @@ -41,7 +41,7 @@ func TestPatchMissingServiceID(t *testing.T) { func TestPutMissingServiceID(t *testing.T) { t.Parallel() - _, err := p.Put(&p.PutInput[p.NullInput, p.NullOutput]{ + _, err := productcore.Put[*productcore.NullInput, *productcore.NullOutput](&productcore.PutInput[*productcore.NullInput]{ ServiceID: "", }) diff --git a/internal/products/types.go b/internal/productcore/types.go similarity index 55% rename from internal/products/types.go rename to internal/productcore/types.go index be6959142..382b05ea7 100644 --- a/internal/products/types.go +++ b/internal/productcore/types.go @@ -1,11 +1,12 @@ -package products +package productcore // ProductOutput is an interface used to constrain the 'O' type -// parameter of the FunctionalTest constructors in this package. Use -// of this interface allows those 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. +// 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. @@ -24,10 +25,10 @@ type NullInput struct{} // Output struct type NullOutput struct{} -func (o NullOutput) ProductID() *string { +func (o *NullOutput) ProductID() *string { return nil } -func (o NullOutput) ServiceID() *string { +func (o *NullOutput) ServiceID() *string { return nil } diff --git a/internal/products/utils.go b/internal/productcore/utils.go similarity index 94% rename from internal/products/utils.go rename to internal/productcore/utils.go index d62cd3656..4a83feeac 100644 --- a/internal/products/utils.go +++ b/internal/productcore/utils.go @@ -1,4 +1,4 @@ -package products +package productcore import "github.com/fastly/go-fastly/v9/fastly" diff --git a/internal/products/api_get.go b/internal/products/api_get.go deleted file mode 100644 index f8f8e735e..000000000 --- a/internal/products/api_get.go +++ /dev/null @@ -1,45 +0,0 @@ -package products - -import "github.com/fastly/go-fastly/v9/fastly" - -// GetInput specifies the information needed for the Get() -// function to perform the operation. -// -// Because Get operations produce output, this struct has a type -// parameter used to specify the type of the output; the parameter is -// not used within this structure, but specifying it at this level -// makes type inference simpler when the caller invokes the Get() -// function. -type GetInput[O ProductOutput] struct { - Client *fastly.Client - ProductID string - ServiceID string - URLComponents []string -} - -// Get implements a product-specific 'get' operation. -// -// This function requires the same type parameter as the GetInput -// struct, 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, error) { - var err error - if i.ServiceID == "" { - return nil, fastly.ErrMissingServiceID - } - - path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) - - resp, err := i.Client.GetJSON(path, nil) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var h *O - if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { - return nil, err - } - - return h, nil -} diff --git a/internal/products/api_patch.go b/internal/products/api_patch.go deleted file mode 100644 index af3c50d02..000000000 --- a/internal/products/api_patch.go +++ /dev/null @@ -1,48 +0,0 @@ -package products - -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 and produce output, this struct -// has two type parameters used to specify the types of the input and -// output; the output parameter is not used within this structure, but -// specifying it at this level makes type inference simpler when the -// caller invokes the Patch() function. -type PatchInput[I any, O ProductOutput] 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 parameters as the PatchInput -// struct; the input type parameter is used to marshal the input data -// into the request body (encoded as JSON), and the output type -// parameter is used to construct, populate, and return the output -// present in the response body. -func Patch[I any, O ProductOutput](i *PatchInput[I, O]) (*O, error) { - var err error - if i.ServiceID == "" { - return nil, fastly.ErrMissingServiceID - } - - path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) - - resp, err := i.Client.PatchJSON(path, i.Input, nil) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var h *O - if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { - return nil, err - } - - return h, nil -} diff --git a/internal/products/api_put.go b/internal/products/api_put.go deleted file mode 100644 index 42ab2aa96..000000000 --- a/internal/products/api_put.go +++ /dev/null @@ -1,48 +0,0 @@ -package products - -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 and produce output, this struct -// has two type parameters used to specify the types of the input and -// output; the output parameter is not used within this structure, but -// specifying it at this level makes type inference simpler when the -// caller invokes the Put() function. -type PutInput[I any, O ProductOutput] 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 parameters as the PutInput -// struct; the input type parameter is used to marshal the input data -// into the request body (encoded as JSON), and the output type -// parameter is used to construct, populate, and return the output -// present in the response body. -func Put[I any, O ProductOutput](i *PutInput[I, O]) (*O, error) { - var err error - if i.ServiceID == "" { - return nil, fastly.ErrMissingServiceID - } - - path := makeURL(i.ProductID, i.ServiceID, i.URLComponents) - - resp, err := i.Client.PutJSON(path, i.Input, nil) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var h *O - if err = fastly.DecodeBodyMap(resp.Body, &h); err != nil { - return nil, err - } - - return h, nil -} From 4cc01ebffa1925129ae92e33f7e1ee866a569f83 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Sat, 14 Dec 2024 10:35:09 -0500 Subject: [PATCH 7/8] More review feedback: Reverse order of input and output type parameters, which allows one of them to be inferred. --- fastly/products/bot_management/api.go | 2 +- fastly/products/bot_management/api_test.go | 2 +- fastly/products/brotli_compression/api.go | 2 +- fastly/products/brotli_compression/api_test.go | 2 +- fastly/products/ddos_protection/api.go | 4 ++-- fastly/products/ddos_protection/api_test.go | 4 ++-- fastly/products/domain_inspector/api.go | 2 +- fastly/products/domain_inspector/api_test.go | 2 +- fastly/products/fanout/api.go | 2 +- fastly/products/fanout/api_test.go | 2 +- fastly/products/image_optimizer/api.go | 2 +- fastly/products/image_optimizer/api_test.go | 2 +- fastly/products/log_explorer_insights/api.go | 2 +- fastly/products/log_explorer_insights/api_test.go | 2 +- fastly/products/ngwaf/api.go | 4 ++-- fastly/products/ngwaf/api_test.go | 4 ++-- fastly/products/origin_inspector/api.go | 2 +- fastly/products/origin_inspector/api_test.go | 2 +- fastly/products/websockets/api.go | 2 +- fastly/products/websockets/api_test.go | 2 +- internal/productcore/api_patch.go | 2 +- internal/productcore/api_put.go | 2 +- internal/productcore/functional_test_enable.go | 4 ++-- internal/productcore/functional_test_update_configuration.go | 4 ++-- internal/productcore/productcore_test.go | 4 ++-- 25 files changed, 32 insertions(+), 32 deletions(-) diff --git a/fastly/products/bot_management/api.go b/fastly/products/bot_management/api.go index 715ee291b..d4b4e260e 100644 --- a/fastly/products/bot_management/api.go +++ b/fastly/products/bot_management/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Bot Management product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/bot_management/api_test.go b/fastly/products/bot_management/api_test.go index 5b8791da5..e58c6872f 100644 --- a/fastly/products/bot_management/api_test.go +++ b/fastly/products/bot_management/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: bot_management.Enable, ProductID: bot_management.ProductID, ServiceID: serviceID, diff --git a/fastly/products/brotli_compression/api.go b/fastly/products/brotli_compression/api.go index f2747c0f7..e0f3be96f 100644 --- a/fastly/products/brotli_compression/api.go +++ b/fastly/products/brotli_compression/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Brotli Compression product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/brotli_compression/api_test.go b/fastly/products/brotli_compression/api_test.go index 67ba8f95a..13a71b8ac 100644 --- a/fastly/products/brotli_compression/api_test.go +++ b/fastly/products/brotli_compression/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: brotli_compression.Enable, ProductID: brotli_compression.ProductID, ServiceID: serviceID, diff --git a/fastly/products/ddos_protection/api.go b/fastly/products/ddos_protection/api.go index a42c5ae42..b4ddb8a71 100644 --- a/fastly/products/ddos_protection/api.go +++ b/fastly/products/ddos_protection/api.go @@ -37,7 +37,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the DDoS Protection product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -69,7 +69,7 @@ func UpdateConfiguration(c *fastly.Client, serviceID string, i *ConfigureInput) return nil, ErrMissingMode } - return productcore.Patch[*ConfigureInput, *ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ + return productcore.Patch[*ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/ddos_protection/api_test.go b/fastly/products/ddos_protection/api_test.go index 8cf1bda67..f1bdc027a 100644 --- a/fastly/products/ddos_protection/api_test.go +++ b/fastly/products/ddos_protection/api_test.go @@ -35,7 +35,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: ddos_protection.Enable, ProductID: ddos_protection.ProductID, ServiceID: serviceID, @@ -56,7 +56,7 @@ var functionalTests = []*fastly.FunctionalTest{ require.Equalf(t, "log", *o.Configuration.Mode, "test '%s'", tc.Name) }, }), - productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ddos_protection.ConfigureInput, *ddos_protection.ConfigureOutput]{ + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ddos_protection.ConfigureOutput, *ddos_protection.ConfigureInput]{ OpFn: ddos_protection.UpdateConfiguration, Input: &ddos_protection.ConfigureInput{Mode: "block"}, ProductID: ddos_protection.ProductID, diff --git a/fastly/products/domain_inspector/api.go b/fastly/products/domain_inspector/api.go index 12fba953d..cbe9659e6 100644 --- a/fastly/products/domain_inspector/api.go +++ b/fastly/products/domain_inspector/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Domain Inspector product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/domain_inspector/api_test.go b/fastly/products/domain_inspector/api_test.go index f57033e7f..d36f599d7 100644 --- a/fastly/products/domain_inspector/api_test.go +++ b/fastly/products/domain_inspector/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: domain_inspector.Enable, ProductID: domain_inspector.ProductID, ServiceID: serviceID, diff --git a/fastly/products/fanout/api.go b/fastly/products/fanout/api.go index c6529b667..39548ec9d 100644 --- a/fastly/products/fanout/api.go +++ b/fastly/products/fanout/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Fanout product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/fanout/api_test.go b/fastly/products/fanout/api_test.go index 63389da85..bf061a78b 100644 --- a/fastly/products/fanout/api_test.go +++ b/fastly/products/fanout/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: fanout.Enable, ProductID: fanout.ProductID, ServiceID: serviceID, diff --git a/fastly/products/image_optimizer/api.go b/fastly/products/image_optimizer/api.go index 5e9523d23..d808c8af3 100644 --- a/fastly/products/image_optimizer/api.go +++ b/fastly/products/image_optimizer/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Image Optimizer product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/image_optimizer/api_test.go b/fastly/products/image_optimizer/api_test.go index 8677a026a..c247c7b4f 100644 --- a/fastly/products/image_optimizer/api_test.go +++ b/fastly/products/image_optimizer/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: image_optimizer.Enable, ProductID: image_optimizer.ProductID, ServiceID: serviceID, diff --git a/fastly/products/log_explorer_insights/api.go b/fastly/products/log_explorer_insights/api.go index 2867330a7..82b1dfbaa 100644 --- a/fastly/products/log_explorer_insights/api.go +++ b/fastly/products/log_explorer_insights/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // 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[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ 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 index db96a80b3..95d9f8a26 100644 --- a/fastly/products/log_explorer_insights/api_test.go +++ b/fastly/products/log_explorer_insights/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: log_explorer_insights.Enable, ProductID: log_explorer_insights.ProductID, ServiceID: serviceID, diff --git a/fastly/products/ngwaf/api.go b/fastly/products/ngwaf/api.go index 8e78eb699..092b70fff 100644 --- a/fastly/products/ngwaf/api.go +++ b/fastly/products/ngwaf/api.go @@ -47,7 +47,7 @@ func Enable(c *fastly.Client, serviceID string, i *EnableInput) (*products.Enabl return nil, ErrMissingWorkspaceID } - return productcore.Put[*EnableInput, *products.EnableOutput](&productcore.PutInput[*EnableInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*EnableInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, @@ -76,7 +76,7 @@ func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, err // 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[*ConfigureInput, *ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ + return productcore.Patch[*ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/ngwaf/api_test.go b/fastly/products/ngwaf/api_test.go index 162696379..a45603147 100644 --- a/fastly/products/ngwaf/api_test.go +++ b/fastly/products/ngwaf/api_test.go @@ -35,7 +35,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*ngwaf.EnableInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *ngwaf.EnableInput]{ OpWithInputFn: ngwaf.Enable, Input: &ngwaf.EnableInput{WorkspaceID: fastly.TestNGWAFWorkspaceID}, ProductID: ngwaf.ProductID, @@ -57,7 +57,7 @@ var functionalTests = []*fastly.FunctionalTest{ require.Equalf(t, "100", *output.Configuration.TrafficRamp, "test '%s'", tc.Name) }, }), - productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ngwaf.ConfigureInput, *ngwaf.ConfigureOutput]{ + productcore.NewUpdateConfigurationTest(&productcore.UpdateConfigurationTestInput[*ngwaf.ConfigureOutput, *ngwaf.ConfigureInput]{ OpFn: ngwaf.UpdateConfiguration, Input: &ngwaf.ConfigureInput{TrafficRamp: "45"}, ProductID: ngwaf.ProductID, diff --git a/fastly/products/origin_inspector/api.go b/fastly/products/origin_inspector/api.go index d5d142314..64429ef31 100644 --- a/fastly/products/origin_inspector/api.go +++ b/fastly/products/origin_inspector/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the Origin Inspector product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/origin_inspector/api_test.go b/fastly/products/origin_inspector/api_test.go index cf0931115..360851110 100644 --- a/fastly/products/origin_inspector/api_test.go +++ b/fastly/products/origin_inspector/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: origin_inspector.Enable, ProductID: origin_inspector.ProductID, ServiceID: serviceID, diff --git a/fastly/products/websockets/api.go b/fastly/products/websockets/api.go index 65a866529..521b82218 100644 --- a/fastly/products/websockets/api.go +++ b/fastly/products/websockets/api.go @@ -19,7 +19,7 @@ func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { // Enable enables the WebSockets product on the service. func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) { - return productcore.Put[*productcore.NullInput, *products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ + return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{ Client: c, ProductID: ProductID, ServiceID: serviceID, diff --git a/fastly/products/websockets/api_test.go b/fastly/products/websockets/api_test.go index 68ffc7699..7787917e8 100644 --- a/fastly/products/websockets/api_test.go +++ b/fastly/products/websockets/api_test.go @@ -25,7 +25,7 @@ var functionalTests = []*fastly.FunctionalTest{ ServiceID: serviceID, ExpectFailure: true, }), - productcore.NewEnableTest(&productcore.EnableTestInput[*productcore.NullInput, *products.EnableOutput]{ + productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{ OpNoInputFn: websockets.Enable, ProductID: websockets.ProductID, ServiceID: serviceID, diff --git a/internal/productcore/api_patch.go b/internal/productcore/api_patch.go index c2a54185e..d04834568 100644 --- a/internal/productcore/api_patch.go +++ b/internal/productcore/api_patch.go @@ -25,7 +25,7 @@ type PatchInput[I any] struct { // interface which matches the ProductOutput interface, and that type // is used to construct, populate, and return the output present in // the response body. -func Patch[I any, O ProductOutput](i *PatchInput[I]) (o O, err error) { +func Patch[O ProductOutput, I any](i *PatchInput[I]) (o O, err error) { if i.ServiceID == "" { err = fastly.ErrMissingServiceID return diff --git a/internal/productcore/api_put.go b/internal/productcore/api_put.go index df0af702f..616886ebb 100644 --- a/internal/productcore/api_put.go +++ b/internal/productcore/api_put.go @@ -25,7 +25,7 @@ type PutInput[I any] struct { // interface which matches the ProductOutput interface, and that type // is used to construct, populate, and return the output present in // the response body. -func Put[I any, O ProductOutput](i *PutInput[I]) (o O, err error) { +func Put[O ProductOutput, I any](i *PutInput[I]) (o O, err error) { if i.ServiceID == "" { err = fastly.ErrMissingServiceID return diff --git a/internal/productcore/functional_test_enable.go b/internal/productcore/functional_test_enable.go index 769e92ab9..bee3a69ba 100644 --- a/internal/productcore/functional_test_enable.go +++ b/internal/productcore/functional_test_enable.go @@ -15,7 +15,7 @@ import ( // 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[I any, O ProductOutput] struct { +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 @@ -58,7 +58,7 @@ type EnableTestInput[I any, O ProductOutput] struct { // 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[I any, O ProductOutput](i *EnableTestInput[I, O]) *fastly.FunctionalTest { +func NewEnableTest[O ProductOutput, I any](i *EnableTestInput[O, I]) *fastly.FunctionalTest { r := fastly.FunctionalTest{} if i.Phase != "" { diff --git a/internal/productcore/functional_test_update_configuration.go b/internal/productcore/functional_test_update_configuration.go index 912da0ed6..3454ec654 100644 --- a/internal/productcore/functional_test_update_configuration.go +++ b/internal/productcore/functional_test_update_configuration.go @@ -17,7 +17,7 @@ import ( // constrained to match the ProductOutput interface (in this package) // so that the test case can validate the common portions of the // output. -type UpdateConfigurationTestInput[I any, O ProductOutput] struct { +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 @@ -57,7 +57,7 @@ type UpdateConfigurationTestInput[I any, O ProductOutput] struct { // UpdateConfigurationTestInput struct, and that type is used to // construct, populate, and validate the output present in the // response body. -func NewUpdateConfigurationTest[I any, O ProductOutput](i *UpdateConfigurationTestInput[I, O]) *fastly.FunctionalTest { +func NewUpdateConfigurationTest[O ProductOutput, I any](i *UpdateConfigurationTestInput[O, I]) *fastly.FunctionalTest { r := fastly.FunctionalTest{} if i.Phase != "" { diff --git a/internal/productcore/productcore_test.go b/internal/productcore/productcore_test.go index 69f9f4ae9..272ce1d93 100644 --- a/internal/productcore/productcore_test.go +++ b/internal/productcore/productcore_test.go @@ -31,7 +31,7 @@ func TestGetMissingServiceID(t *testing.T) { func TestPatchMissingServiceID(t *testing.T) { t.Parallel() - _, err := productcore.Patch[*productcore.NullInput, *productcore.NullOutput](&productcore.PatchInput[*productcore.NullInput]{ + _, err := productcore.Patch[*productcore.NullOutput](&productcore.PatchInput[*productcore.NullInput]{ ServiceID: "", }) @@ -41,7 +41,7 @@ func TestPatchMissingServiceID(t *testing.T) { func TestPutMissingServiceID(t *testing.T) { t.Parallel() - _, err := productcore.Put[*productcore.NullInput, *productcore.NullOutput](&productcore.PutInput[*productcore.NullInput]{ + _, err := productcore.Put[*productcore.NullOutput](&productcore.PutInput[*productcore.NullInput]{ ServiceID: "", }) From 6144a31d743cb89ca780d1eff92754596f561254 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Sat, 14 Dec 2024 10:55:23 -0500 Subject: [PATCH 8/8] More review feedback: Move new functional-testing support into internal/test_utils package. --- fastly/fastly_test_utils.go | 43 ---------------- fastly/products/bot_management/api_test.go | 5 +- .../products/brotli_compression/api_test.go | 5 +- fastly/products/ddos_protection/api_test.go | 11 ++-- fastly/products/domain_inspector/api_test.go | 5 +- fastly/products/fanout/api_test.go | 5 +- fastly/products/image_optimizer/api_test.go | 5 +- .../log_explorer_insights/api_test.go | 5 +- fastly/products/ngwaf/api_test.go | 11 ++-- fastly/products/origin_inspector/api_test.go | 5 +- fastly/products/websockets/api_test.go | 5 +- internal/productcore/api_get.go | 2 +- internal/productcore/api_patch.go | 2 +- internal/productcore/api_put.go | 2 +- .../productcore/functional_test_disable.go | 7 +-- .../productcore/functional_test_enable.go | 11 ++-- internal/productcore/functional_test_get.go | 9 ++-- .../functional_test_get_configuration.go | 9 ++-- .../functional_test_update_configuration.go | 9 ++-- internal/productcore/functional_test_utils.go | 4 +- internal/test_utils/doc.go | 3 ++ internal/test_utils/functional.go | 51 +++++++++++++++++++ 22 files changed, 120 insertions(+), 94 deletions(-) create mode 100644 internal/test_utils/doc.go create mode 100644 internal/test_utils/functional.go diff --git a/fastly/fastly_test_utils.go b/fastly/fastly_test_utils.go index ab3132595..1d8fb8731 100644 --- a/fastly/fastly_test_utils.go +++ b/fastly/fastly_test_utils.go @@ -8,7 +8,6 @@ import ( "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" - "github.com/stretchr/testify/require" ) // TestClient is the test client. @@ -667,45 +666,3 @@ Wm7DCfrPNGVwFWUQOmsPue9rZBgO -----END CERTIFICATE----- ` } - -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, *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 { - Record(t, tc.Operation, func(c *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/fastly/products/bot_management/api_test.go b/fastly/products/bot_management/api_test.go index e58c6872f..2222f22e6 100644 --- a/fastly/products/bot_management/api_test.go +++ b/fastly/products/bot_management/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: bot_management.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/brotli_compression/api_test.go b/fastly/products/brotli_compression/api_test.go index 13a71b8ac..1b7925bd6 100644 --- a/fastly/products/brotli_compression/api_test.go +++ b/fastly/products/brotli_compression/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: brotli_compression.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/ddos_protection/api_test.go b/fastly/products/ddos_protection/api_test.go index f1bdc027a..0cc433dbf 100644 --- a/fastly/products/ddos_protection/api_test.go +++ b/fastly/products/ddos_protection/api_test.go @@ -7,6 +7,7 @@ import ( "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" ) @@ -21,7 +22,7 @@ func TestUpdateConfigurationMissingMode(t *testing.T) { require.ErrorIs(t, err, ddos_protection.ErrMissingMode) } -var functionalTests = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: ddos_protection.Disable, @@ -51,7 +52,7 @@ var functionalTests = []*fastly.FunctionalTest{ OpFn: ddos_protection.GetConfiguration, ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, o *ddos_protection.ConfigureOutput) { + 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) }, @@ -61,7 +62,7 @@ var functionalTests = []*fastly.FunctionalTest{ Input: &ddos_protection.ConfigureInput{Mode: "block"}, ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, o *ddos_protection.ConfigureOutput) { + 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) }, @@ -71,7 +72,7 @@ var functionalTests = []*fastly.FunctionalTest{ OpFn: ddos_protection.GetConfiguration, ProductID: ddos_protection.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, o *ddos_protection.ConfigureOutput) { + 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) }, @@ -90,5 +91,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablementAndConfiguration(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/domain_inspector/api_test.go b/fastly/products/domain_inspector/api_test.go index d36f599d7..fe426ae79 100644 --- a/fastly/products/domain_inspector/api_test.go +++ b/fastly/products/domain_inspector/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: domain_inspector.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/fanout/api_test.go b/fastly/products/fanout/api_test.go index bf061a78b..177c7b279 100644 --- a/fastly/products/fanout/api_test.go +++ b/fastly/products/fanout/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: fanout.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/image_optimizer/api_test.go b/fastly/products/image_optimizer/api_test.go index c247c7b4f..20535913e 100644 --- a/fastly/products/image_optimizer/api_test.go +++ b/fastly/products/image_optimizer/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: image_optimizer.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/log_explorer_insights/api_test.go b/fastly/products/log_explorer_insights/api_test.go index 95d9f8a26..2657faefa 100644 --- a/fastly/products/log_explorer_insights/api_test.go +++ b/fastly/products/log_explorer_insights/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: log_explorer_insights.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/ngwaf/api_test.go b/fastly/products/ngwaf/api_test.go index a45603147..1bae43fdf 100644 --- a/fastly/products/ngwaf/api_test.go +++ b/fastly/products/ngwaf/api_test.go @@ -7,6 +7,7 @@ import ( "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" ) @@ -21,7 +22,7 @@ func TestEnableMissingWorkspaceID(t *testing.T) { require.ErrorIs(t, err, ngwaf.ErrMissingWorkspaceID) } -var functionalTests = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: ngwaf.Disable, @@ -52,7 +53,7 @@ var functionalTests = []*fastly.FunctionalTest{ OpFn: ngwaf.GetConfiguration, ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *ngwaf.ConfigureOutput) { + 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) }, @@ -62,7 +63,7 @@ var functionalTests = []*fastly.FunctionalTest{ Input: &ngwaf.ConfigureInput{TrafficRamp: "45"}, ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *ngwaf.ConfigureOutput) { + 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) }, @@ -72,7 +73,7 @@ var functionalTests = []*fastly.FunctionalTest{ OpFn: ngwaf.GetConfiguration, ProductID: ngwaf.ProductID, ServiceID: serviceID, - CheckOutputFn: func(t *testing.T, tc *fastly.FunctionalTest, output *ngwaf.ConfigureOutput) { + 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) }, @@ -91,5 +92,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablementAndConfiguration(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/origin_inspector/api_test.go b/fastly/products/origin_inspector/api_test.go index 360851110..0c8b839ea 100644 --- a/fastly/products/origin_inspector/api_test.go +++ b/fastly/products/origin_inspector/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: origin_inspector.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/fastly/products/websockets/api_test.go b/fastly/products/websockets/api_test.go index 7787917e8..ee5f82f35 100644 --- a/fastly/products/websockets/api_test.go +++ b/fastly/products/websockets/api_test.go @@ -7,11 +7,12 @@ import ( "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 = []*fastly.FunctionalTest{ +var functionalTests = []*test_utils.FunctionalTest{ productcore.NewDisableTest(&productcore.DisableTestInput{ Phase: "ensure disabled before testing", OpFn: websockets.Disable, @@ -50,5 +51,5 @@ var functionalTests = []*fastly.FunctionalTest{ } func TestEnablement(t *testing.T) { - fastly.ExecuteFunctionalTests(t, functionalTests) + test_utils.ExecuteFunctionalTests(t, functionalTests) } diff --git a/internal/productcore/api_get.go b/internal/productcore/api_get.go index 26da17b7e..3c0258c14 100644 --- a/internal/productcore/api_get.go +++ b/internal/productcore/api_get.go @@ -14,7 +14,7 @@ type GetInput struct { // Get implements a product-specific 'get' operation. // // This function requires a type parameter which is a pointer to an -// interface which matches the ProductOutput interface, and that type +// 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) { diff --git a/internal/productcore/api_patch.go b/internal/productcore/api_patch.go index d04834568..b46c5d254 100644 --- a/internal/productcore/api_patch.go +++ b/internal/productcore/api_patch.go @@ -22,7 +22,7 @@ type PatchInput[I any] struct { // into the request body (encoded as JSON). // // It also requires a type parameter which is a pointer to an -// interface which matches the ProductOutput interface, and that type +// 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) { diff --git a/internal/productcore/api_put.go b/internal/productcore/api_put.go index 616886ebb..e3849ec24 100644 --- a/internal/productcore/api_put.go +++ b/internal/productcore/api_put.go @@ -22,7 +22,7 @@ type PutInput[I any] struct { // into the request body (encoded as JSON). // // It also requires a type parameter which is a pointer to an -// interface which matches the ProductOutput interface, and that type +// 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) { diff --git a/internal/productcore/functional_test_disable.go b/internal/productcore/functional_test_disable.go index d58f73e0c..ce327e1c6 100644 --- a/internal/productcore/functional_test_disable.go +++ b/internal/productcore/functional_test_disable.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" ) // DisableTestInput specifies the information needed for the @@ -30,8 +31,8 @@ type DisableTestInput struct { // NewDisableTest constructs a FunctionalTest object as specified by // its input. -func NewDisableTest(i *DisableTestInput) *fastly.FunctionalTest { - r := fastly.FunctionalTest{} +func NewDisableTest(i *DisableTestInput) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} if i.Phase != "" { r.Name = "disable " + i.Phase @@ -41,7 +42,7 @@ func NewDisableTest(i *DisableTestInput) *fastly.FunctionalTest { r.Operation = "disable" } - r.TestFn = func(_ *testing.T, _ *fastly.FunctionalTest, c *fastly.Client) error { + r.TestFn = func(_ *testing.T, _ *test_utils.FunctionalTest, c *fastly.Client) error { err := i.OpFn(c, i.ServiceID) return err } diff --git a/internal/productcore/functional_test_enable.go b/internal/productcore/functional_test_enable.go index bee3a69ba..f17572c2c 100644 --- a/internal/productcore/functional_test_enable.go +++ b/internal/productcore/functional_test_enable.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" ) // EnableTestInput specifies the information needed for the @@ -45,7 +46,7 @@ type EnableTestInput[O ProductOutput, I any] struct { // 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, *fastly.FunctionalTest, O) + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) } // NewEnableTest constructs a FunctionalTest object as specified by its @@ -58,8 +59,8 @@ type EnableTestInput[O ProductOutput, I any] struct { // 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]) *fastly.FunctionalTest { - r := fastly.FunctionalTest{} +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 @@ -71,7 +72,7 @@ func NewEnableTest[O ProductOutput, I any](i *EnableTestInput[O, I]) *fastly.Fun switch any(i.Input).(type) { case *NullInput: - r.TestFn = func(t *testing.T, tc *fastly.FunctionalTest, c *fastly.Client) error { + 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) @@ -82,7 +83,7 @@ func NewEnableTest[O ProductOutput, I any](i *EnableTestInput[O, I]) *fastly.Fun return err } default: - r.TestFn = func(t *testing.T, tc *fastly.FunctionalTest, c *fastly.Client) error { + 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) diff --git a/internal/productcore/functional_test_get.go b/internal/productcore/functional_test_get.go index b7fa8fbb8..636f31cd8 100644 --- a/internal/productcore/functional_test_get.go +++ b/internal/productcore/functional_test_get.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" "github.com/stretchr/testify/require" ) @@ -41,7 +42,7 @@ type GetTestInput[O ProductOutput] struct { // 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, *fastly.FunctionalTest, O) + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) } // NewGetTest constructs a FunctionalTest object as specified by its @@ -56,8 +57,8 @@ type GetTestInput[O ProductOutput] struct { // 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]) *fastly.FunctionalTest { - r := fastly.FunctionalTest{} +func NewGetTest[O ProductOutput](i *GetTestInput[O]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} if i.Phase != "" { r.Name = "get status " + i.Phase @@ -67,7 +68,7 @@ func NewGetTest[O ProductOutput](i *GetTestInput[O]) *fastly.FunctionalTest { r.Operation = "get" } - r.TestFn = func(t *testing.T, tc *fastly.FunctionalTest, c *fastly.Client) error { + 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) diff --git a/internal/productcore/functional_test_get_configuration.go b/internal/productcore/functional_test_get_configuration.go index c5be84123..f829c7b08 100644 --- a/internal/productcore/functional_test_get_configuration.go +++ b/internal/productcore/functional_test_get_configuration.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" ) // GetConfigurationTestInput specifies the information needed for the @@ -41,13 +42,13 @@ type GetConfigurationTestInput[O ProductOutput] struct { // 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, *fastly.FunctionalTest, O) + 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]) *fastly.FunctionalTest { - r := fastly.FunctionalTest{} +func NewGetConfigurationTest[O ProductOutput](i *GetConfigurationTestInput[O]) *test_utils.FunctionalTest { + r := test_utils.FunctionalTest{} if i.Phase != "" { r.Name = "get configuration " + i.Phase @@ -57,7 +58,7 @@ func NewGetConfigurationTest[O ProductOutput](i *GetConfigurationTestInput[O]) * r.Operation = "get-configuration" } - r.TestFn = func(t *testing.T, tc *fastly.FunctionalTest, c *fastly.Client) error { + 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) diff --git a/internal/productcore/functional_test_update_configuration.go b/internal/productcore/functional_test_update_configuration.go index 3454ec654..1d2266129 100644 --- a/internal/productcore/functional_test_update_configuration.go +++ b/internal/productcore/functional_test_update_configuration.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" ) // UpdateConfigurationTestInput specifies the information needed for @@ -44,7 +45,7 @@ type UpdateConfigurationTestInput[O ProductOutput, I any] struct { // 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, *fastly.FunctionalTest, O) + CheckOutputFn func(*testing.T, *test_utils.FunctionalTest, O) } // NewUpdateConfigurationTest constructs a FunctionalTest object as @@ -57,8 +58,8 @@ type UpdateConfigurationTestInput[O ProductOutput, I any] struct { // 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]) *fastly.FunctionalTest { - r := fastly.FunctionalTest{} +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 @@ -68,7 +69,7 @@ func NewUpdateConfigurationTest[O ProductOutput, I any](i *UpdateConfigurationTe r.Operation = "update-configuration" } - r.TestFn = func(t *testing.T, tc *fastly.FunctionalTest, c *fastly.Client) error { + 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) diff --git a/internal/productcore/functional_test_utils.go b/internal/productcore/functional_test_utils.go index 56b6216c5..e758a3446 100644 --- a/internal/productcore/functional_test_utils.go +++ b/internal/productcore/functional_test_utils.go @@ -3,7 +3,7 @@ package productcore import ( "testing" - "github.com/fastly/go-fastly/v9/fastly" + "github.com/fastly/go-fastly/v9/internal/test_utils" "github.com/stretchr/testify/require" ) @@ -14,7 +14,7 @@ import ( // 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 *fastly.FunctionalTest, o ProductOutput, productID, serviceID string) { +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) 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) + } + } +}