From b9ac80404771c061ccb53da6a2e13c41728a1d82 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Wed, 5 Jul 2023 12:23:35 +1000 Subject: [PATCH] resource_container: add explicit `Type` field for `ResourceContainer` Extend the resource container object to have an explicit `Type` instead of inferring/manipulating from the `Level`. --- .changelog/1325.txt | 3 +++ resource.go | 57 +++++++++++++++++++++++++++++++++++++++++---- resource_test.go | 38 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 .changelog/1325.txt diff --git a/.changelog/1325.txt b/.changelog/1325.txt new file mode 100644 index 00000000000..0742b1f7fc5 --- /dev/null +++ b/.changelog/1325.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource_container: expose `Type` on `*ResourceContainer` to explicitly denote what type of resource it is instead of inferring from `Level`. +``` diff --git a/resource.go b/resource.go index 481eae25ac7..d7819759307 100644 --- a/resource.go +++ b/resource.go @@ -2,13 +2,30 @@ package cloudflare import "fmt" -// RouteLevel holds the "level" where the resource resides. +// RouteLevel holds the "level" where the resource resides. Commonly used in +// routing configurations or builders. type RouteLevel string +// ResourceType holds the type of the resource. This is similar to `RouteLevel` +// however this is the singular version of `RouteLevel` and isn't suitable for +// use in routing. +type ResourceType string + const ( - AccountRouteLevel RouteLevel = "accounts" - ZoneRouteLevel RouteLevel = "zones" - UserRouteLevel RouteLevel = "user" + user = "user" + zone = "zone" + account = "account" + + zones = zone + "s" + accounts = account + "s" + + AccountRouteLevel RouteLevel = accounts + ZoneRouteLevel RouteLevel = zones + UserRouteLevel RouteLevel = user + + AccountType ResourceType = account + ZoneType ResourceType = zone + UserType ResourceType = user ) // ResourceContainer defines an API resource you wish to target. Should not be @@ -17,6 +34,33 @@ const ( type ResourceContainer struct { Level RouteLevel Identifier string + Type ResourceType +} + +func (r RouteLevel) String() string { + switch r { + case AccountRouteLevel: + return accounts + case ZoneRouteLevel: + return zones + case UserRouteLevel: + return user + default: + return "unknown" + } +} + +func (r ResourceType) String() string { + switch r { + case AccountType: + return account + case ZoneType: + return zone + case UserType: + return user + default: + return "unknown" + } } // Returns a URL fragment of the endpoint scoped by the container. @@ -29,7 +73,7 @@ func (rc *ResourceContainer) URLFragment() string { } if rc.Level == UserRouteLevel { - return "user" + return user } return fmt.Sprintf("%s/%s", rc.Level, rc.Identifier) @@ -47,6 +91,7 @@ func UserIdentifier(id string) *ResourceContainer { return &ResourceContainer{ Level: UserRouteLevel, Identifier: id, + Type: UserType, } } @@ -55,6 +100,7 @@ func ZoneIdentifier(id string) *ResourceContainer { return &ResourceContainer{ Level: ZoneRouteLevel, Identifier: id, + Type: ZoneType, } } @@ -63,5 +109,6 @@ func AccountIdentifier(id string) *ResourceContainer { return &ResourceContainer{ Level: AccountRouteLevel, Identifier: id, + Type: AccountType, } } diff --git a/resource_test.go b/resource_test.go index 0a9e82caa08..ad2e7295a36 100644 --- a/resource_test.go +++ b/resource_test.go @@ -6,6 +6,44 @@ import ( "github.com/stretchr/testify/assert" ) +func TestResourceProperties(t *testing.T) { + testCases := map[string]struct { + container *ResourceContainer + expectedRoute string + expectedType string + expectedIdentifier string + }{ + account: { + container: AccountIdentifier("abcd1234"), + expectedRoute: accounts, + expectedType: account, + expectedIdentifier: "abcd1234", + }, + zone: { + container: ZoneIdentifier("abcd1234"), + expectedRoute: zones, + expectedType: zone, + expectedIdentifier: "abcd1234", + }, + user: { + container: UserIdentifier("abcd1234"), + expectedRoute: user, + expectedType: user, + expectedIdentifier: "abcd1234", + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + setup() + defer teardown() + + assert.Equal(t, tc.container.Level.String(), tc.expectedRoute) + assert.Equal(t, tc.container.Type.String(), tc.expectedType) + assert.Equal(t, tc.container.Identifier, tc.expectedIdentifier) + }) + } +} func TestResourcURLFragment(t *testing.T) { tests := map[string]struct { container *ResourceContainer