diff --git a/admin_run.go b/admin_run.go index bc7532f61..181855bd7 100644 --- a/admin_run.go +++ b/admin_run.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "strings" @@ -102,7 +101,7 @@ type AdminRunForceCancelOptions struct { // https://www.terraform.io/docs/cloud/api/admin/runs.html#force-a-run-into-the-quot-cancelled-quot-state func (s *adminRuns) ForceCancel(ctx context.Context, runID string, options AdminRunForceCancelOptions) error { if !validStringID(&runID) { - return errors.New("invalid value for run ID") + return ErrInvalidRunID } u := fmt.Sprintf("admin/runs/%s/actions/force-cancel", url.QueryEscape(runID)) diff --git a/errors.go b/errors.go index 6bba23cf6..143c4630b 100644 --- a/errors.go +++ b/errors.go @@ -12,17 +12,25 @@ var ( // ErrResourceNotFound is returned when receiving a 404. ErrResourceNotFound = errors.New("resource not found") - // ErrRequiredName is returned when a name option is not present. - ErrRequiredName = errors.New("name is required") - - // ErrInvalidName is returned when the name option has invalid value. - ErrInvalidName = errors.New("invalid value for name") - // ErrMissingDirectory is returned when the path does not have an existing directory. ErrMissingDirectory = errors.New("path needs to be an existing directory") ) -// Resource Errors +// Options/fields that cannot be defined +var ( + ErrUnsupportedOperations = errors.New("operations is deprecated and cannot be specified when execution mode is used") + + ErrUnsupportedPrivateKey = errors.New("private Key can only be present with Azure DevOps Server service provider") +) + +// internal errors +var ( + ErrInvalidRequestBody = errors.New("go-tfe bug: DELETE/PATCH/POST body must be nil, ptr, or ptr slice") + + ErrInvalidStructFormat = errors.New("go-tfe bug: struct can't use both json and jsonapi attributes") +) + +// Run Errors var ( // ErrWorkspaceLocked is returned when trying to lock a // locked workspace. @@ -35,74 +43,180 @@ var ( // ErrWorkspaceLockedByRun is returned when trying to unlock a // workspace locked by a run ErrWorkspaceLockedByRun = errors.New("unable to unlock workspace locked by run") +) - // ErrInvalidWorkspaceID is returned when the workspace ID is invalid. +// Invalid values for resources/struct fields +var ( ErrInvalidWorkspaceID = errors.New("invalid value for workspace ID") - // ErrInvalidWorkspaceValue is returned when workspace value is invalid. ErrInvalidWorkspaceValue = errors.New("invalid value for workspace") - // ErrWorkspacesRequired is returned when the Workspaces are not present. - ErrWorkspacesRequired = errors.New("workspaces is required") + ErrInvalidTerraformVersionID = errors.New("invalid value for terraform version ID") - // ErrWorkspaceMinLimit is returned when the length of Workspaces is 0. - ErrWorkspaceMinLimit = errors.New("must provide at least one workspace") + ErrInvalidTerraformVersionType = errors.New("invalid type for terraform version. Please use 'terraform-version'") - // ErrMissingTagIdentifier is returned when tag resource identifiers are invalid - ErrMissingTagIdentifier = errors.New("must specify at least one tag by ID or name") + ErrInvalidConfigVersionID = errors.New("invalid value for configuration version ID") - // Run/Apply errors + ErrInvalidCostEstimateID = errors.New("invalid value for cost estimate ID") + + ErrInvalidSMTPAuth = errors.New("invalid smtp auth type") + + ErrInvalidAgentPoolID = errors.New("invalid value for agent pool ID") + + ErrInvalidAgentTokenID = errors.New("invalid value for agent token ID") - // ErrInvalidRunID is returned when the run ID is invalid. ErrInvalidRunID = errors.New("invalid value for run ID") - // ErrInvalidApplyID is returned when the apply ID is invalid. ErrInvalidApplyID = errors.New("invalid value for apply ID") - // Organzation errors - - // ErrInvalidOrg is returned when the organization option has an invalid value. ErrInvalidOrg = errors.New("invalid value for organization") - // Agent errors + ErrInvalidName = errors.New("invalid value for name") - // ErrInvalidAgentPoolID is returned when the agent pool ID is invalid. - ErrInvalidAgentPoolID = errors.New("invalid value for agent pool ID") + ErrInvalidNotificationConfigID = errors.New("invalid value for notification configuration ID") - // ErrInvalidAgentTokenID is returned when the agent toek ID is invalid. - ErrInvalidAgentTokenID = errors.New("invalid value for agent token ID") + ErrInvalidMembership = errors.New("invalid value for membership") - // Token errors + ErrInvalidMembershipIDs = errors.New("invalid value for organization membership ids") - // ErrAgentTokenDescription is returned when the description is blank. - ErrAgentTokenDescription = errors.New("agent token description can't be blank") + ErrInvalidOauthClientID = errors.New("invalid value for OAuth client ID") - // Config errors + ErrInvalidOauthTokenID = errors.New("invalid value for OAuth token ID") - // ErrInvalidConfigVersionID is returned when the configuration version ID is invalid. - ErrInvalidConfigVersionID = errors.New("invalid value for configuration version ID") + ErrInvalidPolicySetID = errors.New("invalid value for policy set ID") - // Cost Esimation Errors + ErrInvalidPolicyCheckID = errors.New("invalid value for policy check ID") - // ErrInvalidCostEstimateID is returned when the cost estimate ID is invalid. - ErrInvalidCostEstimateID = errors.New("invalid value for cost estimate ID") + ErrInvalidTag = errors.New("invalid tag id") + + ErrInvalidPlanExportID = errors.New("invalid value for plan export ID") + + ErrInvalidPlanID = errors.New("invalid value for plan ID") + + ErrInvalidParamID = errors.New("invalid value for parameter ID") + + ErrInvalidPolicyID = errors.New("invalid value for policy ID") + + ErrInvalidProvider = errors.New("invalid value for provider") - // User + ErrInvalidVersion = errors.New("invalid value for version") + + ErrInvalidRunTriggerID = errors.New("invalid value for run trigger ID") + + ErrInvalidSHHKeyID = errors.New("invalid value for SSH key ID") + + ErrInvalidStateVerID = errors.New("invalid value for state version ID") + + ErrInvalidAccessTeamID = errors.New("invalid value for team access ID") + + ErrInvalidTeamID = errors.New("invalid value for team ID") + + ErrInvalidUsernames = errors.New("invalid value for usernames") + + ErrInvalidUserID = errors.New("invalid value for user ID") - // ErrInvalidUservalue is invalid. ErrInvalidUserValue = errors.New("invalid value for user") - // Settings + ErrInvalidTokenID = errors.New("invalid value for token ID") - // ErrInvalidSMTPAuth is returned when the smtp auth type is not valid. - ErrInvalidSMTPAuth = errors.New("invalid smtp auth type") + ErrInvalidCategory = errors.New("category must be policy-set") - // Terraform Versions + ErrInvalidPolicies = errors.New("must provide at least one policy") - // ErrInvalidTerraformVersionID is returned when the ID for a terraform - // version is invalid. - ErrInvalidTerraformVersionID = errors.New("invalid value for terraform version ID") + ErrInvalidVariableID = errors.New("invalid value for variable ID") +) - // ErrInvalidTerraformVersionType is returned when the type is not valid. - ErrInvalidTerraformVersionType = errors.New("invalid type for terraform version. Please use 'terraform-version'") +// Missing required field/option +var ( + ErrRequiredAccess = errors.New("access is required") + + ErrRequiredAgentPoolID = errors.New("'agent' execution mode requires an agent pool ID to be specified") + + ErrRequiredAgentMode = errors.New("specifying an agent pool ID requires 'agent' execution mode") + + ErrRequiredCategory = errors.New("category is required") + + ErrRequiredDestinationType = errors.New("destination type is required") + + ErrRequiredDataType = errors.New("data type is required") + + ErrRequiredKey = errors.New("key is required") + + ErrRequiredName = errors.New("name is required") + + ErrRequiredEnabled = errors.New("enabled is required") + + ErrRequiredEnforce = errors.New("enforce is required") + + ErrRequiredEnforcementPath = errors.New("enforcement path is required") + + ErrRequiredEnforcementMode = errors.New("enforcement mode is required") + + ErrRequiredEmail = errors.New("email is required") + + ErrRequiredM5 = errors.New("MD5 is required") + + ErrRequiredURL = errors.New("url is required") + + ErrRequiredAPIURL = errors.New("API URL is required") + + ErrRequiredHTTPURL = errors.New("HTTP URL is required") + + ErrRequiredServiceProvider = errors.New("service provider is required") + + ErrRequiredProvider = errors.New("provider is required") + + ErrRequiredOauthToken = errors.New("OAuth token is required") + + ErrRequiredOauthTokenID = errors.New("oauth token ID is required") + + ErrMissingTagIdentifier = errors.New("must specify at least one tag by ID or name") + + ErrAgentTokenDescription = errors.New("agent token description can't be blank") + + ErrRequiredTagID = errors.New("you must specify at least one tag id to remove") + + ErrRequiredTagWorkspaceID = errors.New("you must specify at least one workspace to add tag to") + + ErrRequiredWorkspace = errors.New("workspace is required") + + ErrRequiredWorkspaceID = errors.New("workspace ID is required") + + ErrWorkspacesRequired = errors.New("workspaces is required") + + ErrWorkspaceMinLimit = errors.New("must provide at least one workspace") + + ErrRequiredPlan = errors.New("plan is required") + + ErrRequiredPolicies = errors.New("policies is required") + + ErrRequiredVersion = errors.New("version is required") + + ErrRequiredVCSRepo = errors.New("vcs repo is required") + + ErrRequiredIdentifier = errors.New("identifier is required") + + ErrRequiredDisplayIdentifier = errors.New("display identifier is required") + + ErrRequiredSourceable = errors.New("sourceable is required") + + ErrRequiredValue = errors.New("value is required") + + ErrRequiredOrg = errors.New("organization is required") + + ErrRequiredTeam = errors.New("team is required") + + ErrRequiredStateVerListOps = errors.New("StateVersionListOptions is required") + + ErrRequireTeamAccessListOps = errors.New("TeamAccessListOptions is required") + + ErrRequiredSerial = errors.New("serial is required") + + ErrRequiredState = errors.New("state is required") + + ErrRequiredSHHKeyID = errors.New("SSH key ID is required") + + ErrRequiredOnlyOneField = errors.New("only one of usernames or organization membership ids can be provided") + + ErrRequiredUsernameOrMembershipIds = errors.New("usernames or organization membership ids are required") ) diff --git a/notification_configuration.go b/notification_configuration.go index ed0f0b718..1752d235f 100644 --- a/notification_configuration.go +++ b/notification_configuration.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -164,10 +163,10 @@ type NotificationConfigurationCreateOptions struct { func (o NotificationConfigurationCreateOptions) valid() error { if o.DestinationType == nil { - return errors.New("destination type is required") + return ErrRequiredDestinationType } if o.Enabled == nil { - return errors.New("enabled is required") + return ErrRequiredEnabled } if !validString(o.Name) { return ErrRequiredName @@ -175,7 +174,7 @@ func (o NotificationConfigurationCreateOptions) valid() error { if *o.DestinationType == NotificationDestinationTypeGeneric || *o.DestinationType == NotificationDestinationTypeSlack { if o.URL == nil { - return errors.New("url is required") + return ErrRequiredURL } } return nil @@ -208,7 +207,7 @@ func (s *notificationConfigurations) Create(ctx context.Context, workspaceID str // Read a notification configuration by its ID. func (s *notificationConfigurations) Read(ctx context.Context, notificationConfigurationID string) (*NotificationConfiguration, error) { if !validStringID(¬ificationConfigurationID) { - return nil, errors.New("invalid value for notification configuration ID") + return nil, ErrInvalidNotificationConfigID } u := fmt.Sprintf("notification-configurations/%s", url.QueryEscape(notificationConfigurationID)) @@ -261,7 +260,7 @@ type NotificationConfigurationUpdateOptions struct { // Updates a notification configuration with the given options. func (s *notificationConfigurations) Update(ctx context.Context, notificationConfigurationID string, options NotificationConfigurationUpdateOptions) (*NotificationConfiguration, error) { if !validStringID(¬ificationConfigurationID) { - return nil, errors.New("invalid value for notification configuration ID") + return nil, ErrInvalidNotificationConfigID } u := fmt.Sprintf("notification-configurations/%s", url.QueryEscape(notificationConfigurationID)) @@ -282,7 +281,7 @@ func (s *notificationConfigurations) Update(ctx context.Context, notificationCon // Delete a notifications configuration by its ID. func (s *notificationConfigurations) Delete(ctx context.Context, notificationConfigurationID string) error { if !validStringID(¬ificationConfigurationID) { - return errors.New("invalid value for notification configuration ID") + return ErrInvalidNotificationConfigID } u := fmt.Sprintf("notification-configurations/%s", url.QueryEscape(notificationConfigurationID)) @@ -298,7 +297,7 @@ func (s *notificationConfigurations) Delete(ctx context.Context, notificationCon // payload to the configured url. func (s *notificationConfigurations) Verify(ctx context.Context, notificationConfigurationID string) (*NotificationConfiguration, error) { if !validStringID(¬ificationConfigurationID) { - return nil, errors.New("invalid value for notification configuration ID") + return nil, ErrInvalidNotificationConfigID } u := fmt.Sprintf( diff --git a/notification_configuration_integration_test.go b/notification_configuration_integration_test.go index e4b9d2492..c28e7c19a 100644 --- a/notification_configuration_integration_test.go +++ b/notification_configuration_integration_test.go @@ -125,7 +125,7 @@ func TestNotificationConfigurationCreate(t *testing.T) { nc, err := client.NotificationConfigurations.Create(ctx, wTest.ID, options) assert.Nil(t, nc) - assert.EqualError(t, err, "url is required") + assert.Equal(t, err, ErrRequiredURL) }) t.Run("without a valid workspace", func(t *testing.T) { @@ -178,7 +178,7 @@ func TestNotificationConfigurationRead(t *testing.T) { t.Run("when the notification configuration ID is invalid", func(t *testing.T) { _, err := client.NotificationConfigurations.Read(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for notification configuration ID") + assert.Equal(t, err, ErrInvalidNotificationConfigID) }) } @@ -265,7 +265,7 @@ func TestNotificationConfigurationUpdate(t *testing.T) { t.Run("when the notification configuration ID is invalid", func(t *testing.T) { _, err := client.NotificationConfigurations.Update(ctx, badIdentifier, NotificationConfigurationUpdateOptions{}) - assert.EqualError(t, err, "invalid value for notification configuration ID") + assert.Equal(t, err, ErrInvalidNotificationConfigID) }) } @@ -293,7 +293,7 @@ func TestNotificationConfigurationDelete(t *testing.T) { t.Run("when the notification configuration ID is invalid", func(t *testing.T) { err := client.NotificationConfigurations.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for notification configuration ID") + assert.Equal(t, err, ErrInvalidNotificationConfigID) }) } @@ -316,6 +316,6 @@ func TestNotificationConfigurationVerify(t *testing.T) { t.Run("when the notification configuration ID is invalid", func(t *testing.T) { _, err := client.NotificationConfigurations.Verify(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for notification configuration ID") + assert.Equal(t, err, ErrInvalidNotificationConfigID) }) } diff --git a/oauth_client.go b/oauth_client.go index 96a1d2300..6fb6139d5 100644 --- a/oauth_client.go +++ b/oauth_client.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -149,19 +148,19 @@ type OAuthClientCreateOptions struct { func (o OAuthClientCreateOptions) valid() error { if !validString(o.APIURL) { - return errors.New("API URL is required") + return ErrRequiredAPIURL } if !validString(o.HTTPURL) { - return errors.New("HTTP URL is required") + return ErrRequiredHTTPURL } if o.ServiceProvider == nil { - return errors.New("service provider is required") + return ErrRequiredServiceProvider } if !validString(o.OAuthToken) && *o.ServiceProvider != *ServiceProvider(ServiceProviderBitbucketServer) { - return errors.New("OAuth token is required") + return ErrRequiredOauthToken } if validString(o.PrivateKey) && *o.ServiceProvider != *ServiceProvider(ServiceProviderAzureDevOpsServer) { - return errors.New("private Key can only be present with Azure DevOps Server service provider") + return ErrUnsupportedPrivateKey } return nil } @@ -193,7 +192,7 @@ func (s *oAuthClients) Create(ctx context.Context, organization string, options // Read an OAuth client by its ID. func (s *oAuthClients) Read(ctx context.Context, oAuthClientID string) (*OAuthClient, error) { if !validStringID(&oAuthClientID) { - return nil, errors.New("invalid value for OAuth client ID") + return nil, ErrInvalidOauthClientID } u := fmt.Sprintf("oauth-clients/%s", url.QueryEscape(oAuthClientID)) @@ -239,7 +238,7 @@ type OAuthClientUpdateOptions struct { // Update an OAuth client by its ID. func (s *oAuthClients) Update(ctx context.Context, oAuthClientID string, options OAuthClientUpdateOptions) (*OAuthClient, error) { if !validStringID(&oAuthClientID) { - return nil, errors.New("invalid value for OAuth client ID") + return nil, ErrInvalidOauthClientID } u := fmt.Sprintf("oauth-clients/%s", url.QueryEscape(oAuthClientID)) @@ -260,7 +259,7 @@ func (s *oAuthClients) Update(ctx context.Context, oAuthClientID string, options // Delete an OAuth client by its ID. func (s *oAuthClients) Delete(ctx context.Context, oAuthClientID string) error { if !validStringID(&oAuthClientID) { - return errors.New("invalid value for OAuth client ID") + return ErrInvalidOauthClientID } u := fmt.Sprintf("oauth-clients/%s", url.QueryEscape(oAuthClientID)) diff --git a/oauth_client_integration_test.go b/oauth_client_integration_test.go index a098690ae..75dbd050d 100644 --- a/oauth_client_integration_test.go +++ b/oauth_client_integration_test.go @@ -127,7 +127,7 @@ func TestOAuthClientsCreate(t *testing.T) { } _, err := client.OAuthClients.Create(ctx, orgTest.Name, options) - assert.EqualError(t, err, "API URL is required") + assert.Equal(t, err, ErrRequiredAPIURL) }) t.Run("without a HTTP URL", func(t *testing.T) { @@ -138,7 +138,7 @@ func TestOAuthClientsCreate(t *testing.T) { } _, err := client.OAuthClients.Create(ctx, orgTest.Name, options) - assert.EqualError(t, err, "HTTP URL is required") + assert.Equal(t, err, ErrRequiredHTTPURL) }) t.Run("without an OAuth token", func(t *testing.T) { @@ -149,7 +149,7 @@ func TestOAuthClientsCreate(t *testing.T) { } _, err := client.OAuthClients.Create(ctx, orgTest.Name, options) - assert.EqualError(t, err, "OAuth token is required") + assert.Equal(t, err, ErrRequiredOauthToken) }) t.Run("without a service provider", func(t *testing.T) { @@ -160,7 +160,7 @@ func TestOAuthClientsCreate(t *testing.T) { } _, err := client.OAuthClients.Create(ctx, orgTest.Name, options) - assert.EqualError(t, err, "service provider is required") + assert.Equal(t, err, ErrRequiredServiceProvider) }) } @@ -222,7 +222,7 @@ func TestOAuthClientsRead(t *testing.T) { t.Run("without a valid OAuth client ID", func(t *testing.T) { oc, err := client.OAuthClients.Read(ctx, badIdentifier) assert.Nil(t, oc) - assert.EqualError(t, err, "invalid value for OAuth client ID") + assert.Equal(t, err, ErrInvalidOauthClientID) }) } @@ -251,7 +251,7 @@ func TestOAuthClientsDelete(t *testing.T) { t.Run("when the OAuth client ID is invalid", func(t *testing.T) { err := client.OAuthClients.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for OAuth client ID") + assert.Equal(t, err, ErrInvalidOauthClientID) }) } @@ -276,7 +276,7 @@ func TestOAuthClientsCreateOptionsValid(t *testing.T) { } err := options.valid() - assert.EqualError(t, err, "API URL is required") + assert.Equal(t, err, ErrRequiredAPIURL) }) t.Run("without a HTTP URL", func(t *testing.T) { @@ -287,7 +287,7 @@ func TestOAuthClientsCreateOptionsValid(t *testing.T) { } err := options.valid() - assert.EqualError(t, err, "HTTP URL is required") + assert.Equal(t, err, ErrRequiredHTTPURL) }) t.Run("without an OAuth token", func(t *testing.T) { @@ -298,7 +298,7 @@ func TestOAuthClientsCreateOptionsValid(t *testing.T) { } err := options.valid() - assert.EqualError(t, err, "OAuth token is required") + assert.Equal(t, err, ErrRequiredOauthToken) }) t.Run("without a service provider", func(t *testing.T) { @@ -309,7 +309,7 @@ func TestOAuthClientsCreateOptionsValid(t *testing.T) { } err := options.valid() - assert.EqualError(t, err, "service provider is required") + assert.Equal(t, err, ErrRequiredServiceProvider) }) t.Run("without private key and not ado_server options", func(t *testing.T) { @@ -347,7 +347,7 @@ func TestOAuthClientsCreateOptionsValid(t *testing.T) { } err := options.valid() - assert.EqualError(t, err, "private Key can only be present with Azure DevOps Server service provider") + assert.Equal(t, err, ErrUnsupportedPrivateKey) }) t.Run("with valid options including private key", func(t *testing.T) { diff --git a/oauth_token.go b/oauth_token.go index 0f0d3c969..705c89e7a 100644 --- a/oauth_token.go +++ b/oauth_token.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -83,7 +82,7 @@ func (s *oAuthTokens) List(ctx context.Context, organization string, options *OA // Read an OAuth token by its ID. func (s *oAuthTokens) Read(ctx context.Context, oAuthTokenID string) (*OAuthToken, error) { if !validStringID(&oAuthTokenID) { - return nil, errors.New("invalid value for OAuth token ID") + return nil, ErrInvalidOauthTokenID } u := fmt.Sprintf("oauth-tokens/%s", url.QueryEscape(oAuthTokenID)) @@ -116,7 +115,7 @@ type OAuthTokenUpdateOptions struct { // Update an existing OAuth token. func (s *oAuthTokens) Update(ctx context.Context, oAuthTokenID string, options OAuthTokenUpdateOptions) (*OAuthToken, error) { if !validStringID(&oAuthTokenID) { - return nil, errors.New("invalid value for OAuth token ID") + return nil, ErrInvalidOauthTokenID } u := fmt.Sprintf("oauth-tokens/%s", url.QueryEscape(oAuthTokenID)) @@ -137,7 +136,7 @@ func (s *oAuthTokens) Update(ctx context.Context, oAuthTokenID string, options O // Delete an OAuth token by its ID. func (s *oAuthTokens) Delete(ctx context.Context, oAuthTokenID string) error { if !validStringID(&oAuthTokenID) { - return errors.New("invalid value for OAuth token ID") + return ErrInvalidOauthTokenID } u := fmt.Sprintf("oauth-tokens/%s", url.QueryEscape(oAuthTokenID)) diff --git a/oauth_token_integration_test.go b/oauth_token_integration_test.go index 476cfe9de..af0f9d5d9 100644 --- a/oauth_token_integration_test.go +++ b/oauth_token_integration_test.go @@ -98,7 +98,7 @@ func TestOAuthTokensRead(t *testing.T) { t.Run("without a valid OAuth token ID", func(t *testing.T) { ot, err := client.OAuthTokens.Read(ctx, badIdentifier) assert.Nil(t, ot) - assert.EqualError(t, err, "invalid value for OAuth token ID") + assert.Equal(t, err, ErrInvalidOauthTokenID) }) } @@ -156,7 +156,7 @@ dpIe8YOINN27XaojJvVpT5uBVCcZLF+G7kaMjSwCTlDx3Q== t.Run("without a valid policy ID", func(t *testing.T) { ot, err := client.OAuthTokens.Update(ctx, badIdentifier, OAuthTokenUpdateOptions{}) assert.Nil(t, ot) - assert.EqualError(t, err, "invalid value for OAuth token ID") + assert.Equal(t, err, ErrInvalidOauthTokenID) }) } @@ -186,6 +186,6 @@ func TestOAuthTokensDelete(t *testing.T) { t.Run("when the OAuth token ID is invalid", func(t *testing.T) { err := client.OAuthTokens.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for OAuth token ID") + assert.Equal(t, err, ErrInvalidOauthTokenID) }) } diff --git a/organization.go b/organization.go index 483841a78..6faf9320f 100644 --- a/organization.go +++ b/organization.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -183,7 +182,7 @@ func (o OrganizationCreateOptions) valid() error { return ErrInvalidName } if !validString(o.Email) { - return errors.New("email is required") + return ErrRequiredEmail } return nil } diff --git a/organization_integration_test.go b/organization_integration_test.go index 23ac898be..f017a0576 100644 --- a/organization_integration_test.go +++ b/organization_integration_test.go @@ -81,7 +81,7 @@ func TestOrganizationsCreate(t *testing.T) { Name: String("foo"), }) assert.Nil(t, org) - assert.EqualError(t, err, "email is required") + assert.Equal(t, err, ErrRequiredEmail) }) t.Run("when no name is provided", func(t *testing.T) { diff --git a/organization_membership.go b/organization_membership.go index 6bac0c8c5..c0eb004d9 100644 --- a/organization_membership.go +++ b/organization_membership.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -114,7 +113,7 @@ type OrganizationMembershipCreateOptions struct { func (o OrganizationMembershipCreateOptions) valid() error { if o.Email == nil { - return errors.New("email is required") + return ErrRequiredEmail } return nil } @@ -156,7 +155,7 @@ type OrganizationMembershipReadOptions struct { // Read an organization membership by ID with options func (s *organizationMemberships) ReadWithOptions(ctx context.Context, organizationMembershipID string, options OrganizationMembershipReadOptions) (*OrganizationMembership, error) { if !validStringID(&organizationMembershipID) { - return nil, errors.New("invalid value for membership") + return nil, ErrInvalidMembership } u := fmt.Sprintf("organization-memberships/%s", url.QueryEscape(organizationMembershipID)) @@ -177,7 +176,7 @@ func (s *organizationMemberships) ReadWithOptions(ctx context.Context, organizat // Delete an organization membership by its ID. func (s *organizationMemberships) Delete(ctx context.Context, organizationMembershipID string) error { if !validStringID(&organizationMembershipID) { - return errors.New("invalid value for membership") + return ErrInvalidMembership } u := fmt.Sprintf("organization-memberships/%s", url.QueryEscape(organizationMembershipID)) diff --git a/organization_membership_integration_test.go b/organization_membership_integration_test.go index 9d9e8fa4f..fbcbc172c 100644 --- a/organization_membership_integration_test.go +++ b/organization_membership_integration_test.go @@ -106,7 +106,7 @@ func TestOrganizationMembershipsCreate(t *testing.T) { mem, err := client.OrganizationMemberships.Create(ctx, orgTest.Name, OrganizationMembershipCreateOptions{}) assert.Nil(t, mem) - assert.EqualError(t, err, "email is required") + assert.Equal(t, err, ErrRequiredEmail) }) t.Run("with an invalid organization", func(t *testing.T) { @@ -157,7 +157,7 @@ func TestOrganizationMembershipsRead(t *testing.T) { t.Run("with invalid membership id", func(t *testing.T) { mem, err := client.OrganizationMemberships.Read(ctx, badIdentifier) assert.Nil(t, mem) - assert.EqualError(t, err, "invalid value for membership") + assert.Equal(t, err, ErrInvalidMembership) }) } @@ -188,7 +188,7 @@ func TestOrganizationMembershipsReadWithOptions(t *testing.T) { t.Run("with invalid membership id", func(t *testing.T) { mem, err := client.OrganizationMemberships.ReadWithOptions(ctx, badIdentifier, options) assert.Nil(t, mem) - assert.EqualError(t, err, "invalid value for membership") + assert.Equal(t, err, ErrInvalidMembership) }) } @@ -214,7 +214,7 @@ func TestOrganizationMembershipsDelete(t *testing.T) { t.Run("when membership is invalid", func(t *testing.T) { err := client.OrganizationMemberships.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for membership") + assert.Equal(t, err, ErrInvalidMembership) }) t.Run("when an error is returned from the api", func(t *testing.T) { diff --git a/organization_tags.go b/organization_tags.go index fba99f985..a28f432a9 100644 --- a/organization_tags.go +++ b/organization_tags.go @@ -82,7 +82,7 @@ type tagID struct { func (opts *OrganizationTagsDeleteOptions) valid() error { if opts.IDs == nil || len(opts.IDs) == 0 { - return errors.New("you must specify at least one tag id to remove") + return ErrRequiredTagID } for _, id := range opts.IDs { @@ -126,7 +126,7 @@ type AddWorkspacesToTagOptions struct { func (w *AddWorkspacesToTagOptions) valid() error { if w.WorkspaceIDs == nil || len(w.WorkspaceIDs) == 0 { - return errors.New("you must specify at least one workspace to add tag to") + return ErrRequiredTagWorkspaceID } for _, id := range w.WorkspaceIDs { @@ -147,7 +147,7 @@ type workspaceID struct { // Add workspaces to a tag func (s *organizationTags) AddWorkspaces(ctx context.Context, tag string, options AddWorkspacesToTagOptions) error { if !validStringID(&tag) { - return errors.New("invalid tag id") + return ErrInvalidTag } if err := options.valid(); err != nil { diff --git a/plan.go b/plan.go index 011d7f7dc..2657b5f91 100644 --- a/plan.go +++ b/plan.go @@ -3,7 +3,6 @@ package tfe import ( "bytes" "context" - "errors" "fmt" "io" "net/url" @@ -77,7 +76,7 @@ type PlanStatusTimestamps struct { // Read a plan by its ID. func (s *plans) Read(ctx context.Context, planID string) (*Plan, error) { if !validStringID(&planID) { - return nil, errors.New("invalid value for plan ID") + return nil, ErrInvalidPlanID } u := fmt.Sprintf("plans/%s", url.QueryEscape(planID)) @@ -98,7 +97,7 @@ func (s *plans) Read(ctx context.Context, planID string) (*Plan, error) { // Logs retrieves the logs of a plan. func (s *plans) Logs(ctx context.Context, planID string) (io.Reader, error) { if !validStringID(&planID) { - return nil, errors.New("invalid value for plan ID") + return nil, ErrInvalidPlanID } // Get the plan to make sure it exists. @@ -142,7 +141,7 @@ func (s *plans) Logs(ctx context.Context, planID string) (io.Reader, error) { // Retrieve the JSON execution plan func (s *plans) JSONOutput(ctx context.Context, planID string) ([]byte, error) { if !validStringID(&planID) { - return nil, errors.New("invalid value for plan ID") + return nil, ErrInvalidPlanID } u := fmt.Sprintf("plans/%s/json-output", url.QueryEscape(planID)) diff --git a/plan_export.go b/plan_export.go index 4d4ed05dd..1fd837663 100644 --- a/plan_export.go +++ b/plan_export.go @@ -3,7 +3,6 @@ package tfe import ( "bytes" "context" - "errors" "fmt" "net/url" "time" @@ -90,10 +89,10 @@ type PlanExportCreateOptions struct { func (o PlanExportCreateOptions) valid() error { if o.Plan == nil { - return errors.New("plan is required") + return ErrRequiredPlan } if o.DataType == nil { - return errors.New("data type is required") + return ErrRequiredDataType } return nil } @@ -120,7 +119,7 @@ func (s *planExports) Create(ctx context.Context, options PlanExportCreateOption // Read a plan export by its ID. func (s *planExports) Read(ctx context.Context, planExportID string) (*PlanExport, error) { if !validStringID(&planExportID) { - return nil, errors.New("invalid value for plan export ID") + return nil, ErrInvalidPlanExportID } u := fmt.Sprintf("plan-exports/%s", url.QueryEscape(planExportID)) @@ -141,7 +140,7 @@ func (s *planExports) Read(ctx context.Context, planExportID string) (*PlanExpor // Delete a plan export by ID. func (s *planExports) Delete(ctx context.Context, planExportID string) error { if !validStringID(&planExportID) { - return errors.New("invalid value for plan export ID") + return ErrInvalidPlanExportID } u := fmt.Sprintf("plan-exports/%s", url.QueryEscape(planExportID)) @@ -156,7 +155,7 @@ func (s *planExports) Delete(ctx context.Context, planExportID string) error { // Download a plan export's data. Data is exported in a .tar.gz format. func (s *planExports) Download(ctx context.Context, planExportID string) ([]byte, error) { if !validStringID(&planExportID) { - return nil, errors.New("invalid value for plan export ID") + return nil, ErrInvalidPlanExportID } u := fmt.Sprintf("plan-exports/%s/download", url.QueryEscape(planExportID)) diff --git a/plan_export_integration_test.go b/plan_export_integration_test.go index 3fc9956c0..acb2f211b 100644 --- a/plan_export_integration_test.go +++ b/plan_export_integration_test.go @@ -44,7 +44,7 @@ func TestPlanExportsCreate(t *testing.T) { pe, err := client.PlanExports.Create(ctx, options) assert.Nil(t, pe) - assert.EqualError(t, err, "plan is required") + assert.Equal(t, err, ErrRequiredPlan) }) t.Run("without a data type", func(t *testing.T) { @@ -55,7 +55,7 @@ func TestPlanExportsCreate(t *testing.T) { pe, err := client.PlanExports.Create(ctx, options) assert.Nil(t, pe) - assert.EqualError(t, err, "data type is required") + assert.Equal(t, err, ErrRequiredDataType) }) } @@ -78,7 +78,7 @@ func TestPlanExportsRead(t *testing.T) { t.Run("without a valid ID", func(t *testing.T) { pe, err := client.PlanExports.Read(ctx, badIdentifier) assert.Nil(t, pe) - assert.EqualError(t, err, "invalid value for plan export ID") + assert.Equal(t, err, ErrInvalidPlanExportID) }) } @@ -101,7 +101,7 @@ func TestPlanExportsDelete(t *testing.T) { t.Run("without a valid ID", func(t *testing.T) { err := client.PlanExports.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for plan export ID") + assert.Equal(t, err, ErrInvalidPlanExportID) }) } @@ -121,7 +121,7 @@ func TestPlanExportsDownload(t *testing.T) { t.Run("without a valid ID", func(t *testing.T) { pe, err := client.PlanExports.Download(ctx, badIdentifier) assert.Nil(t, pe) - assert.EqualError(t, err, "invalid value for plan export ID") + assert.Equal(t, err, ErrInvalidPlanExportID) }) } diff --git a/plan_integration_test.go b/plan_integration_test.go index 4e914e32d..11200c0f9 100644 --- a/plan_integration_test.go +++ b/plan_integration_test.go @@ -41,7 +41,7 @@ func TestPlansRead(t *testing.T) { t.Run("with invalid plan ID", func(t *testing.T) { p, err := client.Plans.Read(ctx, badIdentifier) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for plan ID") + assert.Equal(t, err, ErrInvalidPlanID) }) } diff --git a/policy.go b/policy.go index 13403504b..8a72eeb5a 100644 --- a/policy.go +++ b/policy.go @@ -3,7 +3,6 @@ package tfe import ( "bytes" "context" - "errors" "fmt" "net/url" "time" @@ -140,14 +139,14 @@ func (o PolicyCreateOptions) valid() error { return ErrInvalidName } if o.Enforce == nil { - return errors.New("enforce is required") + return ErrRequiredEnforce } for _, e := range o.Enforce { if !validString(e.Path) { - return errors.New("enforcement path is required") + return ErrRequiredEnforcementPath } if e.Mode == nil { - return errors.New("enforcement mode is required") + return ErrRequiredEnforcementMode } } return nil @@ -180,7 +179,7 @@ func (s *policies) Create(ctx context.Context, organization string, options Poli // Read a policy by its ID. func (s *policies) Read(ctx context.Context, policyID string) (*Policy, error) { if !validStringID(&policyID) { - return nil, errors.New("invalid value for policy ID") + return nil, ErrInvalidPolicyID } u := fmt.Sprintf("policies/%s", url.QueryEscape(policyID)) @@ -216,7 +215,7 @@ type PolicyUpdateOptions struct { // Update an existing policy. func (s *policies) Update(ctx context.Context, policyID string, options PolicyUpdateOptions) (*Policy, error) { if !validStringID(&policyID) { - return nil, errors.New("invalid value for policy ID") + return nil, ErrInvalidPolicyID } u := fmt.Sprintf("policies/%s", url.QueryEscape(policyID)) @@ -237,7 +236,7 @@ func (s *policies) Update(ctx context.Context, policyID string, options PolicyUp // Delete a policy by its ID. func (s *policies) Delete(ctx context.Context, policyID string) error { if !validStringID(&policyID) { - return errors.New("invalid value for policy ID") + return ErrInvalidPolicyID } u := fmt.Sprintf("policies/%s", url.QueryEscape(policyID)) @@ -252,7 +251,7 @@ func (s *policies) Delete(ctx context.Context, policyID string) error { // Upload the policy content of the policy. func (s *policies) Upload(ctx context.Context, policyID string, content []byte) error { if !validStringID(&policyID) { - return errors.New("invalid value for policy ID") + return ErrInvalidPolicyID } u := fmt.Sprintf("policies/%s/upload", url.QueryEscape(policyID)) @@ -267,7 +266,7 @@ func (s *policies) Upload(ctx context.Context, policyID string, content []byte) // Download the policy content of the policy. func (s *policies) Download(ctx context.Context, policyID string) ([]byte, error) { if !validStringID(&policyID) { - return nil, errors.New("invalid value for policy ID") + return nil, ErrInvalidPolicyID } u := fmt.Sprintf("policies/%s/download", url.QueryEscape(policyID)) diff --git a/policy_check.go b/policy_check.go index 51e12a243..b6fe8776e 100644 --- a/policy_check.go +++ b/policy_check.go @@ -3,7 +3,6 @@ package tfe import ( "bytes" "context" - "errors" "fmt" "io" "net/url" @@ -140,7 +139,7 @@ func (s *policyChecks) List(ctx context.Context, runID string, options *PolicyCh // Read a policy check by its ID. func (s *policyChecks) Read(ctx context.Context, policyCheckID string) (*PolicyCheck, error) { if !validStringID(&policyCheckID) { - return nil, errors.New("invalid value for policy check ID") + return nil, ErrInvalidPolicyCheckID } u := fmt.Sprintf("policy-checks/%s", url.QueryEscape(policyCheckID)) @@ -161,7 +160,7 @@ func (s *policyChecks) Read(ctx context.Context, policyCheckID string) (*PolicyC // Override a soft-mandatory or warning policy. func (s *policyChecks) Override(ctx context.Context, policyCheckID string) (*PolicyCheck, error) { if !validStringID(&policyCheckID) { - return nil, errors.New("invalid value for policy check ID") + return nil, ErrInvalidPolicyCheckID } u := fmt.Sprintf("policy-checks/%s/actions/override", url.QueryEscape(policyCheckID)) @@ -182,7 +181,7 @@ func (s *policyChecks) Override(ctx context.Context, policyCheckID string) (*Pol // Logs retrieves the logs of a policy check. func (s *policyChecks) Logs(ctx context.Context, policyCheckID string) (io.Reader, error) { if !validStringID(&policyCheckID) { - return nil, errors.New("invalid value for policy check ID") + return nil, ErrInvalidPolicyCheckID } // Loop until the context is canceled or the policy check is finished diff --git a/policy_check_integration_test.go b/policy_check_integration_test.go index bedfcf97f..d9e41f51e 100644 --- a/policy_check_integration_test.go +++ b/policy_check_integration_test.go @@ -109,7 +109,7 @@ func TestPolicyChecksRead(t *testing.T) { t.Run("without a valid policy check ID", func(t *testing.T) { pc, err := client.PolicyChecks.Read(ctx, badIdentifier) assert.Nil(t, pc) - assert.EqualError(t, err, "invalid value for policy check ID") + assert.Equal(t, err, ErrInvalidPolicyCheckID) }) } @@ -169,7 +169,7 @@ func TestPolicyChecksOverride(t *testing.T) { t.Run("without a valid policy check ID", func(t *testing.T) { p, err := client.PolicyChecks.Override(ctx, badIdentifier) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for policy check ID") + assert.Equal(t, err, ErrInvalidPolicyCheckID) }) } diff --git a/policy_integration_test.go b/policy_integration_test.go index 439f9d901..2e52b4955 100644 --- a/policy_integration_test.go +++ b/policy_integration_test.go @@ -150,7 +150,7 @@ func TestPoliciesCreate(t *testing.T) { p, err := client.Policies.Create(ctx, orgTest.Name, options) assert.Nil(t, p) - assert.EqualError(t, err, "enforce is required") + assert.Equal(t, err, ErrRequiredEnforce) }) t.Run("when options is missing enforcement path", func(t *testing.T) { @@ -165,7 +165,7 @@ func TestPoliciesCreate(t *testing.T) { p, err := client.Policies.Create(ctx, orgTest.Name, options) assert.Nil(t, p) - assert.EqualError(t, err, "enforcement path is required") + assert.Equal(t, err, ErrRequiredEnforcementPath) }) t.Run("when options is missing enforcement path", func(t *testing.T) { @@ -181,7 +181,7 @@ func TestPoliciesCreate(t *testing.T) { p, err := client.Policies.Create(ctx, orgTest.Name, options) assert.Nil(t, p) - assert.EqualError(t, err, "enforcement mode is required") + assert.Equal(t, err, ErrRequiredEnforcementMode) }) t.Run("when options has an invalid organization", func(t *testing.T) { @@ -242,7 +242,7 @@ func TestPoliciesRead(t *testing.T) { t.Run("without a valid policy ID", func(t *testing.T) { p, err := client.Policies.Read(ctx, badIdentifier) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for policy ID") + assert.Equal(t, err, ErrInvalidPolicyID) }) } @@ -326,7 +326,7 @@ func TestPoliciesUpdate(t *testing.T) { t.Run("without a valid policy ID", func(t *testing.T) { p, err := client.Policies.Update(ctx, badIdentifier, PolicyUpdateOptions{}) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for policy ID") + assert.Equal(t, err, ErrInvalidPolicyID) }) } @@ -357,7 +357,7 @@ func TestPoliciesDelete(t *testing.T) { t.Run("when the policy ID is invalid", func(t *testing.T) { err := client.Policies.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for policy ID") + assert.Equal(t, err, ErrInvalidPolicyID) }) } @@ -387,7 +387,7 @@ func TestPoliciesUpload(t *testing.T) { t.Run("without a valid policy ID", func(t *testing.T) { err := client.Policies.Upload(ctx, badIdentifier, []byte(`main = rule { true }`)) - assert.EqualError(t, err, "invalid value for policy ID") + assert.Equal(t, err, ErrInvalidPolicyID) }) } @@ -419,7 +419,7 @@ func TestPoliciesDownload(t *testing.T) { t.Run("without a valid policy ID", func(t *testing.T) { content, err := client.Policies.Download(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for policy ID") + assert.Equal(t, err, ErrInvalidPolicyID) assert.Nil(t, content) }) } diff --git a/policy_set.go b/policy_set.go index d4524ac5b..428cf914c 100644 --- a/policy_set.go +++ b/policy_set.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -211,7 +210,7 @@ func (s *policySets) Read(ctx context.Context, policySetID string) (*PolicySet, // ReadWithOptions reads a policy by its ID using the options supplied. func (s *policySets) ReadWithOptions(ctx context.Context, policySetID string, options *PolicySetReadOptions) (*PolicySet, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } u := fmt.Sprintf("policy-sets/%s", url.QueryEscape(policySetID)) @@ -270,7 +269,7 @@ func (o PolicySetUpdateOptions) valid() error { // Update an existing policy set. func (s *policySets) Update(ctx context.Context, policySetID string, options PolicySetUpdateOptions) (*PolicySet, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } if err := options.valid(); err != nil { return nil, err @@ -300,10 +299,10 @@ type PolicySetAddPoliciesOptions struct { func (o PolicySetAddPoliciesOptions) valid() error { if o.Policies == nil { - return errors.New("policies is required") + return ErrRequiredPolicies } if len(o.Policies) == 0 { - return errors.New("must provide at least one policy") + return ErrInvalidPolicies } return nil } @@ -311,7 +310,7 @@ func (o PolicySetAddPoliciesOptions) valid() error { // Add policies to a policy set func (s *policySets) AddPolicies(ctx context.Context, policySetID string, options PolicySetAddPoliciesOptions) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } if err := options.valid(); err != nil { return err @@ -335,10 +334,10 @@ type PolicySetRemovePoliciesOptions struct { func (o PolicySetRemovePoliciesOptions) valid() error { if o.Policies == nil { - return errors.New("policies is required") + return ErrRequiredPolicies } if len(o.Policies) == 0 { - return errors.New("must provide at least one policy") + return ErrInvalidPolicies } return nil } @@ -346,7 +345,7 @@ func (o PolicySetRemovePoliciesOptions) valid() error { // Remove policies from a policy set func (s *policySets) RemovePolicies(ctx context.Context, policySetID string, options PolicySetRemovePoliciesOptions) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } if err := options.valid(); err != nil { return err @@ -370,10 +369,10 @@ type PolicySetAddWorkspacesOptions struct { func (o PolicySetAddWorkspacesOptions) valid() error { if o.Workspaces == nil { - return errors.New("workspaces is required") + return ErrWorkspacesRequired } if len(o.Workspaces) == 0 { - return errors.New("must provide at least one workspace") + return ErrWorkspaceMinLimit } return nil } @@ -381,7 +380,7 @@ func (o PolicySetAddWorkspacesOptions) valid() error { // Add workspaces to a policy set. func (s *policySets) AddWorkspaces(ctx context.Context, policySetID string, options PolicySetAddWorkspacesOptions) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } if err := options.valid(); err != nil { return err @@ -405,10 +404,10 @@ type PolicySetRemoveWorkspacesOptions struct { func (o PolicySetRemoveWorkspacesOptions) valid() error { if o.Workspaces == nil { - return errors.New("workspaces is required") + return ErrWorkspacesRequired } if len(o.Workspaces) == 0 { - return errors.New("must provide at least one workspace") + return ErrWorkspaceMinLimit } return nil } @@ -416,7 +415,7 @@ func (o PolicySetRemoveWorkspacesOptions) valid() error { // Remove workspaces from a policy set. func (s *policySets) RemoveWorkspaces(ctx context.Context, policySetID string, options PolicySetRemoveWorkspacesOptions) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } if err := options.valid(); err != nil { return err @@ -434,7 +433,7 @@ func (s *policySets) RemoveWorkspaces(ctx context.Context, policySetID string, o // Delete a policy set by its ID. func (s *policySets) Delete(ctx context.Context, policySetID string) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } u := fmt.Sprintf("policy-sets/%s", url.QueryEscape(policySetID)) diff --git a/policy_set_integration_test.go b/policy_set_integration_test.go index ccc4e468b..63e82041e 100644 --- a/policy_set_integration_test.go +++ b/policy_set_integration_test.go @@ -259,7 +259,7 @@ func TestPolicySetsRead(t *testing.T) { t.Run("without a valid ID", func(t *testing.T) { ps, err := client.PolicySets.Read(ctx, badIdentifier) assert.Nil(t, ps) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) t.Run("with policy set version", func(t *testing.T) { @@ -341,7 +341,7 @@ func TestPolicySetsUpdate(t *testing.T) { Name: String("policy-set"), }) assert.Nil(t, ps) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -382,21 +382,21 @@ func TestPolicySetsAddPolicies(t *testing.T) { t.Run("without policies provided", func(t *testing.T) { err := client.PolicySets.AddPolicies(ctx, psTest.ID, PolicySetAddPoliciesOptions{}) - assert.EqualError(t, err, "policies is required") + assert.Equal(t, err, ErrRequiredPolicies) }) t.Run("with empty policies slice", func(t *testing.T) { err := client.PolicySets.AddPolicies(ctx, psTest.ID, PolicySetAddPoliciesOptions{ Policies: []*Policy{}, }) - assert.EqualError(t, err, "must provide at least one policy") + assert.Equal(t, err, ErrInvalidPolicies) }) t.Run("without a valid ID", func(t *testing.T) { err := client.PolicySets.AddPolicies(ctx, badIdentifier, PolicySetAddPoliciesOptions{ Policies: []*Policy{pTest1, pTest2}, }) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -431,21 +431,21 @@ func TestPolicySetsRemovePolicies(t *testing.T) { t.Run("without policies provided", func(t *testing.T) { err := client.PolicySets.RemovePolicies(ctx, psTest.ID, PolicySetRemovePoliciesOptions{}) - assert.EqualError(t, err, "policies is required") + assert.Equal(t, err, ErrRequiredPolicies) }) t.Run("with empty policies slice", func(t *testing.T) { err := client.PolicySets.RemovePolicies(ctx, psTest.ID, PolicySetRemovePoliciesOptions{ Policies: []*Policy{}, }) - assert.EqualError(t, err, "must provide at least one policy") + assert.Equal(t, err, ErrInvalidPolicies) }) t.Run("without a valid ID", func(t *testing.T) { err := client.PolicySets.RemovePolicies(ctx, badIdentifier, PolicySetRemovePoliciesOptions{ Policies: []*Policy{pTest1, pTest2}, }) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -494,7 +494,7 @@ func TestPolicySetsAddWorkspaces(t *testing.T) { psTest.ID, PolicySetAddWorkspacesOptions{}, ) - assert.EqualError(t, err, "workspaces is required") + assert.Equal(t, err, ErrWorkspacesRequired) }) t.Run("with empty workspaces slice", func(t *testing.T) { @@ -503,7 +503,7 @@ func TestPolicySetsAddWorkspaces(t *testing.T) { psTest.ID, PolicySetAddWorkspacesOptions{Workspaces: []*Workspace{}}, ) - assert.EqualError(t, err, "must provide at least one workspace") + assert.Equal(t, err, ErrWorkspaceMinLimit) }) t.Run("without a valid ID", func(t *testing.T) { @@ -514,7 +514,7 @@ func TestPolicySetsAddWorkspaces(t *testing.T) { Workspaces: []*Workspace{wTest1, wTest2}, }, ) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -557,7 +557,7 @@ func TestPolicySetsRemoveWorkspaces(t *testing.T) { psTest.ID, PolicySetRemoveWorkspacesOptions{}, ) - assert.EqualError(t, err, "workspaces is required") + assert.Equal(t, err, ErrWorkspacesRequired) }) t.Run("with empty workspaces slice", func(t *testing.T) { @@ -566,7 +566,7 @@ func TestPolicySetsRemoveWorkspaces(t *testing.T) { psTest.ID, PolicySetRemoveWorkspacesOptions{Workspaces: []*Workspace{}}, ) - assert.EqualError(t, err, "must provide at least one workspace") + assert.Equal(t, err, ErrWorkspaceMinLimit) }) t.Run("without a valid ID", func(t *testing.T) { @@ -577,7 +577,7 @@ func TestPolicySetsRemoveWorkspaces(t *testing.T) { Workspaces: []*Workspace{wTest1, wTest2}, }, ) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -608,6 +608,6 @@ func TestPolicySetsDelete(t *testing.T) { t.Run("when the policy ID is invalid", func(t *testing.T) { err := client.PolicySets.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } diff --git a/policy_set_parameter.go b/policy_set_parameter.go index e2b5190e6..9f312adce 100644 --- a/policy_set_parameter.go +++ b/policy_set_parameter.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -62,7 +61,7 @@ type PolicySetParameterListOptions struct { // List all the parameters associated with the given policy-set. func (s *policySetParameters) List(ctx context.Context, policySetID string, options *PolicySetParameterListOptions) (*PolicySetParameterList, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } u := fmt.Sprintf("policy-sets/%s/parameters", policySetID) @@ -103,13 +102,13 @@ type PolicySetParameterCreateOptions struct { func (o PolicySetParameterCreateOptions) valid() error { if !validString(o.Key) { - return errors.New("key is required") + return ErrRequiredKey } if o.Category == nil { - return errors.New("category is required") + return ErrRequiredCategory } if *o.Category != CategoryPolicySet { - return errors.New("category must be policy-set") + return ErrInvalidCategory } return nil } @@ -117,7 +116,7 @@ func (o PolicySetParameterCreateOptions) valid() error { // Create is used to create a new parameter. func (s *policySetParameters) Create(ctx context.Context, policySetID string, options PolicySetParameterCreateOptions) (*PolicySetParameter, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } if err := options.valid(); err != nil { return nil, err @@ -141,10 +140,10 @@ func (s *policySetParameters) Create(ctx context.Context, policySetID string, op // Read a parameter by its ID. func (s *policySetParameters) Read(ctx context.Context, policySetID string, parameterID string) (*PolicySetParameter, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } if !validStringID(¶meterID) { - return nil, errors.New("invalid value for parameter ID") + return nil, ErrInvalidParamID } u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID)) @@ -183,10 +182,10 @@ type PolicySetParameterUpdateOptions struct { // Update values of an existing parameter. func (s *policySetParameters) Update(ctx context.Context, policySetID string, parameterID string, options PolicySetParameterUpdateOptions) (*PolicySetParameter, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } if !validStringID(¶meterID) { - return nil, errors.New("invalid value for parameter ID") + return nil, ErrInvalidParamID } u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID)) @@ -207,10 +206,10 @@ func (s *policySetParameters) Update(ctx context.Context, policySetID string, pa // Delete a parameter by its ID. func (s *policySetParameters) Delete(ctx context.Context, policySetID string, parameterID string) error { if !validStringID(&policySetID) { - return errors.New("invalid value for policy set ID") + return ErrInvalidPolicySetID } if !validStringID(¶meterID) { - return errors.New("invalid value for parameter ID") + return ErrInvalidParamID } u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID)) diff --git a/policy_set_parameter_integration_test.go b/policy_set_parameter_integration_test.go index 835e1eee0..1ab4c5c50 100644 --- a/policy_set_parameter_integration_test.go +++ b/policy_set_parameter_integration_test.go @@ -59,7 +59,7 @@ func TestPolicySetParametersList(t *testing.T) { t.Run("when policy set ID is invalid ID", func(t *testing.T) { pl, err := client.PolicySetParameters.List(ctx, badIdentifier, nil) assert.Nil(t, pl) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -129,7 +129,7 @@ func TestPolicySetParametersCreate(t *testing.T) { } _, err := client.PolicySetParameters.Create(ctx, psTest.ID, options) - assert.EqualError(t, err, "key is required") + assert.Equal(t, err, ErrRequiredKey) }) t.Run("when options has an empty key", func(t *testing.T) { @@ -140,7 +140,7 @@ func TestPolicySetParametersCreate(t *testing.T) { } _, err := client.PolicySetParameters.Create(ctx, psTest.ID, options) - assert.EqualError(t, err, "key is required") + assert.Equal(t, err, ErrRequiredKey) }) t.Run("when options is missing category", func(t *testing.T) { @@ -150,7 +150,7 @@ func TestPolicySetParametersCreate(t *testing.T) { } _, err := client.PolicySetParameters.Create(ctx, psTest.ID, options) - assert.EqualError(t, err, "category is required") + assert.Equal(t, err, ErrRequiredCategory) }) t.Run("when policy set ID is invalid", func(t *testing.T) { @@ -161,7 +161,7 @@ func TestPolicySetParametersCreate(t *testing.T) { } _, err := client.PolicySetParameters.Create(ctx, badIdentifier, options) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } @@ -194,13 +194,13 @@ func TestPolicySetParametersRead(t *testing.T) { t.Run("without a valid policy set ID", func(t *testing.T) { p, err := client.PolicySetParameters.Read(ctx, badIdentifier, pTest.ID) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) t.Run("without a valid parameter ID", func(t *testing.T) { p, err := client.PolicySetParameters.Read(ctx, pTest.PolicySet.ID, badIdentifier) assert.Nil(t, p) - assert.EqualError(t, err, "invalid value for parameter ID") + assert.Equal(t, err, ErrInvalidParamID) }) } @@ -261,12 +261,12 @@ func TestPolicySetParametersUpdate(t *testing.T) { t.Run("with invalid parameter ID", func(t *testing.T) { _, err := client.PolicySetParameters.Update(ctx, badIdentifier, pTest.ID, PolicySetParameterUpdateOptions{}) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) t.Run("with invalid parameter ID", func(t *testing.T) { _, err := client.PolicySetParameters.Update(ctx, pTest.PolicySet.ID, badIdentifier, PolicySetParameterUpdateOptions{}) - assert.EqualError(t, err, "invalid value for parameter ID") + assert.Equal(t, err, ErrInvalidParamID) }) } @@ -293,11 +293,11 @@ func TestPolicySetParametersDelete(t *testing.T) { t.Run("with invalid policy set ID", func(t *testing.T) { err := client.PolicySetParameters.Delete(ctx, badIdentifier, pTest.ID) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) t.Run("with invalid parameter ID", func(t *testing.T) { err := client.PolicySetParameters.Delete(ctx, psTest.ID, badIdentifier) - assert.EqualError(t, err, "invalid value for parameter ID") + assert.Equal(t, err, ErrInvalidParamID) }) } diff --git a/policy_set_version.go b/policy_set_version.go index 6c0284413..c5b7fbc66 100644 --- a/policy_set_version.go +++ b/policy_set_version.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -98,7 +97,7 @@ func (p PolicySetVersion) uploadURL() (string, error) { // Create is used to create a new Policy Set Version. func (p *policySetVersions) Create(ctx context.Context, policySetID string) (*PolicySetVersion, error) { if !validStringID(&policySetID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } u := fmt.Sprintf("policy-sets/%s/versions", url.QueryEscape(policySetID)) @@ -119,7 +118,7 @@ func (p *policySetVersions) Create(ctx context.Context, policySetID string) (*Po // Read is used to read a Policy Set Version by its ID. func (p *policySetVersions) Read(ctx context.Context, policySetVersionID string) (*PolicySetVersion, error) { if !validStringID(&policySetVersionID) { - return nil, errors.New("invalid value for policy set ID") + return nil, ErrInvalidPolicySetID } u := fmt.Sprintf("policy-set-versions/%s", url.QueryEscape(policySetVersionID)) diff --git a/policy_set_version_integration_test.go b/policy_set_version_integration_test.go index c3039bff2..cad6b08f0 100644 --- a/policy_set_version_integration_test.go +++ b/policy_set_version_integration_test.go @@ -34,7 +34,7 @@ func TestPolicySetVersionsCreate(t *testing.T) { t.Run("with invalid identifier", func(t *testing.T) { _, err := client.PolicySetVersions.Create(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for policy set ID") + assert.Equal(t, err, ErrInvalidPolicySetID) }) } diff --git a/registry_module.go b/registry_module.go index 45b9abae2..1b8233e16 100644 --- a/registry_module.go +++ b/registry_module.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -158,10 +157,10 @@ func (o RegistryModuleCreateOptions) valid() error { return ErrInvalidName } if !validString(o.Provider) { - return errors.New("provider is required") + return ErrRequiredProvider } if !validStringID(o.Provider) { - return errors.New("invalid value for provider") + return ErrInvalidProvider } return nil } @@ -206,10 +205,10 @@ type RegistryModuleCreateVersionOptions struct { func (o RegistryModuleCreateVersionOptions) valid() error { if !validString(o.Version) { - return errors.New("version is required") + return ErrRequiredVersion } if !validStringID(o.Version) { - return errors.New("invalid value for version") + return ErrInvalidVersion } return nil } @@ -226,10 +225,10 @@ func (r *registryModules) CreateVersion(ctx context.Context, organization string return nil, ErrInvalidName } if !validString(&provider) { - return nil, errors.New("provider is required") + return nil, ErrRequiredProvider } if !validStringID(&provider) { - return nil, errors.New("invalid value for provider") + return nil, ErrInvalidProvider } if err := options.valid(); err != nil { return nil, err @@ -265,7 +264,7 @@ type RegistryModuleCreateWithVCSConnectionOptions struct { func (o RegistryModuleCreateWithVCSConnectionOptions) valid() error { if o.VCSRepo == nil { - return errors.New("vcs repo is required") + return ErrRequiredVCSRepo } return o.VCSRepo.valid() } @@ -278,13 +277,13 @@ type RegistryModuleVCSRepoOptions struct { func (o RegistryModuleVCSRepoOptions) valid() error { if !validString(o.Identifier) { - return errors.New("identifier is required") + return ErrRequiredIdentifier } if !validString(o.OAuthTokenID) { - return errors.New("oauth token ID is required") + return ErrRequiredOauthTokenID } if !validString(o.DisplayIdentifier) { - return errors.New("display identifier is required") + return ErrRequiredDisplayIdentifier } return nil } @@ -324,10 +323,10 @@ func (r *registryModules) Read(ctx context.Context, organization string, name st return nil, ErrInvalidName } if !validString(&provider) { - return nil, errors.New("provider is required") + return nil, ErrRequiredProvider } if !validStringID(&provider) { - return nil, errors.New("invalid value for provider") + return nil, ErrInvalidProvider } u := fmt.Sprintf( @@ -387,10 +386,10 @@ func (r *registryModules) DeleteProvider(ctx context.Context, organization strin return ErrInvalidName } if !validString(&provider) { - return errors.New("provider is required") + return ErrRequiredProvider } if !validStringID(&provider) { - return errors.New("invalid value for provider") + return ErrInvalidProvider } u := fmt.Sprintf( @@ -419,16 +418,16 @@ func (r *registryModules) DeleteVersion(ctx context.Context, organization string return ErrInvalidName } if !validString(&provider) { - return errors.New("provider is required") + return ErrRequiredProvider } if !validStringID(&provider) { - return errors.New("invalid value for provider") + return ErrInvalidProvider } if !validString(&version) { - return errors.New("version is required") + return ErrRequiredVersion } if !validStringID(&version) { - return errors.New("invalid value for version") + return ErrInvalidVersion } u := fmt.Sprintf( diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index 8da04b9e4..c4fa034c1 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -77,7 +77,7 @@ func TestRegistryModulesCreate(t *testing.T) { } rm, err := client.RegistryModules.Create(ctx, orgTest.Name, options) assert.Nil(t, rm) - assert.EqualError(t, err, "provider is required") + assert.Equal(t, err, ErrRequiredProvider) }) t.Run("with an invalid provider", func(t *testing.T) { @@ -87,7 +87,7 @@ func TestRegistryModulesCreate(t *testing.T) { } rm, err := client.RegistryModules.Create(ctx, orgTest.Name, options) assert.Nil(t, rm) - assert.EqualError(t, err, "invalid value for provider") + assert.Equal(t, err, ErrInvalidProvider) }) }) @@ -141,7 +141,7 @@ func TestRegistryModulesCreateVersion(t *testing.T) { options := RegistryModuleCreateVersionOptions{} rmv, err := client.RegistryModules.CreateVersion(ctx, orgTest.Name, registryModuleTest.Name, registryModuleTest.Provider, options) assert.Nil(t, rmv) - assert.EqualError(t, err, "version is required") + assert.Equal(t, err, ErrRequiredVersion) }) t.Run("with invalid version", func(t *testing.T) { @@ -150,7 +150,7 @@ func TestRegistryModulesCreateVersion(t *testing.T) { } rmv, err := client.RegistryModules.CreateVersion(ctx, orgTest.Name, registryModuleTest.Name, registryModuleTest.Provider, options) assert.Nil(t, rmv) - assert.EqualError(t, err, "invalid value for version") + assert.Equal(t, err, ErrInvalidVersion) }) }) @@ -178,7 +178,7 @@ func TestRegistryModulesCreateVersion(t *testing.T) { } rmv, err := client.RegistryModules.CreateVersion(ctx, orgTest.Name, registryModuleTest.Name, "", options) assert.Nil(t, rmv) - assert.EqualError(t, err, "provider is required") + assert.Equal(t, err, ErrRequiredProvider) }) t.Run("with an invalid provider", func(t *testing.T) { @@ -187,7 +187,7 @@ func TestRegistryModulesCreateVersion(t *testing.T) { } rmv, err := client.RegistryModules.CreateVersion(ctx, orgTest.Name, registryModuleTest.Name, badIdentifier, options) assert.Nil(t, rmv) - assert.EqualError(t, err, "invalid value for provider") + assert.Equal(t, err, ErrInvalidProvider) }) t.Run("without a valid organization", func(t *testing.T) { @@ -269,7 +269,7 @@ func TestRegistryModulesCreateWithVCSConnection(t *testing.T) { } rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options) assert.Nil(t, rm) - assert.EqualError(t, err, "identifier is required") + assert.Equal(t, err, ErrRequiredIdentifier) }) t.Run("without an oauth token ID", func(t *testing.T) { @@ -282,7 +282,7 @@ func TestRegistryModulesCreateWithVCSConnection(t *testing.T) { } rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options) assert.Nil(t, rm) - assert.EqualError(t, err, "oauth token ID is required") + assert.Equal(t, err, ErrRequiredOauthTokenID) }) t.Run("without a display identifier", func(t *testing.T) { @@ -295,7 +295,7 @@ func TestRegistryModulesCreateWithVCSConnection(t *testing.T) { } rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options) assert.Nil(t, rm) - assert.EqualError(t, err, "display identifier is required") + assert.Equal(t, err, ErrRequiredDisplayIdentifier) }) }) @@ -303,7 +303,7 @@ func TestRegistryModulesCreateWithVCSConnection(t *testing.T) { options := RegistryModuleCreateWithVCSConnectionOptions{} rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options) assert.Nil(t, rm) - assert.EqualError(t, err, "vcs repo is required") + assert.Equal(t, err, ErrRequiredVCSRepo) }) } @@ -350,13 +350,13 @@ func TestRegistryModulesRead(t *testing.T) { t.Run("without a provider", func(t *testing.T) { rm, err := client.RegistryModules.Read(ctx, orgTest.Name, registryModuleTest.Name, "") assert.Nil(t, rm) - assert.EqualError(t, err, "provider is required") + assert.Equal(t, err, ErrRequiredProvider) }) t.Run("with an invalid provider", func(t *testing.T) { rm, err := client.RegistryModules.Read(ctx, orgTest.Name, registryModuleTest.Name, badIdentifier) assert.Nil(t, rm) - assert.EqualError(t, err, "invalid value for provider") + assert.Equal(t, err, ErrInvalidProvider) }) t.Run("without a valid organization", func(t *testing.T) { @@ -442,12 +442,12 @@ func TestRegistryModulesDeleteProvider(t *testing.T) { t.Run("without a provider", func(t *testing.T) { err := client.RegistryModules.DeleteProvider(ctx, orgTest.Name, registryModuleTest.Name, "") - assert.EqualError(t, err, "provider is required") + assert.Equal(t, err, ErrRequiredProvider) }) t.Run("with an invalid provider", func(t *testing.T) { err := client.RegistryModules.DeleteProvider(ctx, orgTest.Name, registryModuleTest.Name, badIdentifier) - assert.EqualError(t, err, "invalid value for provider") + assert.Equal(t, err, ErrInvalidProvider) }) t.Run("without a valid organization", func(t *testing.T) { @@ -508,22 +508,22 @@ func TestRegistryModulesDeleteVersion(t *testing.T) { t.Run("without a provider", func(t *testing.T) { err := client.RegistryModules.DeleteVersion(ctx, orgTest.Name, registryModuleTest.Name, "", registryModuleTest.VersionStatuses[0].Version) - assert.EqualError(t, err, "provider is required") + assert.Equal(t, err, ErrRequiredProvider) }) t.Run("with an invalid provider", func(t *testing.T) { err := client.RegistryModules.DeleteVersion(ctx, orgTest.Name, registryModuleTest.Name, badIdentifier, registryModuleTest.VersionStatuses[0].Version) - assert.EqualError(t, err, "invalid value for provider") + assert.Equal(t, err, ErrInvalidProvider) }) t.Run("without a version", func(t *testing.T) { err := client.RegistryModules.DeleteVersion(ctx, orgTest.Name, registryModuleTest.Name, registryModuleTest.Provider, "") - assert.EqualError(t, err, "version is required") + assert.Equal(t, err, ErrRequiredVersion) }) t.Run("with an invalid version", func(t *testing.T) { err := client.RegistryModules.DeleteVersion(ctx, orgTest.Name, registryModuleTest.Name, registryModuleTest.Provider, badIdentifier) - assert.EqualError(t, err, "invalid value for version") + assert.Equal(t, err, ErrInvalidVersion) }) t.Run("without a valid organization", func(t *testing.T) { diff --git a/run.go b/run.go index 98f05f3f0..8fc65fca0 100644 --- a/run.go +++ b/run.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -266,7 +265,7 @@ type RunCreateOptions struct { func (o RunCreateOptions) valid() error { if o.Workspace == nil { - return errors.New("workspace is required") + return ErrRequiredWorkspace } return nil } diff --git a/run_integration_test.go b/run_integration_test.go index 2b471e364..cdd3cacb7 100644 --- a/run_integration_test.go +++ b/run_integration_test.go @@ -179,7 +179,7 @@ func TestRunsCreate(t *testing.T) { t.Run("without a workspace", func(t *testing.T) { r, err := client.Runs.Create(ctx, RunCreateOptions{}) assert.Nil(t, r) - assert.EqualError(t, err, "workspace is required") + assert.Equal(t, err, ErrRequiredWorkspace) }) t.Run("with additional attributes", func(t *testing.T) { diff --git a/run_trigger.go b/run_trigger.go index e3ecb120e..d47821963 100644 --- a/run_trigger.go +++ b/run_trigger.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -105,7 +104,7 @@ type RunTriggerCreateOptions struct { func (o RunTriggerCreateOptions) valid() error { if o.Sourceable == nil { - return errors.New("sourceable is required") + return ErrRequiredSourceable } return nil } @@ -137,7 +136,7 @@ func (s *runTriggers) Create(ctx context.Context, workspaceID string, options Ru // Read a run trigger by its ID. func (s *runTriggers) Read(ctx context.Context, runTriggerID string) (*RunTrigger, error) { if !validStringID(&runTriggerID) { - return nil, errors.New("invalid value for run trigger ID") + return nil, ErrInvalidRunTriggerID } u := fmt.Sprintf("run-triggers/%s", url.QueryEscape(runTriggerID)) @@ -158,7 +157,7 @@ func (s *runTriggers) Read(ctx context.Context, runTriggerID string) (*RunTrigge // Delete a run trigger by its ID. func (s *runTriggers) Delete(ctx context.Context, runTriggerID string) error { if !validStringID(&runTriggerID) { - return errors.New("invalid value for run trigger ID") + return ErrInvalidRunTriggerID } u := fmt.Sprintf("run-triggers/%s", url.QueryEscape(runTriggerID)) diff --git a/run_trigger_integration_test.go b/run_trigger_integration_test.go index fd1776ec4..9ad48b202 100644 --- a/run_trigger_integration_test.go +++ b/run_trigger_integration_test.go @@ -130,7 +130,7 @@ func TestRunTriggerCreate(t *testing.T) { rt, err := client.RunTriggers.Create(ctx, wTest.ID, options) assert.Nil(t, rt) - assert.EqualError(t, err, "sourceable is required") + assert.Equal(t, err, ErrRequiredSourceable) }) t.Run("without a valid workspace", func(t *testing.T) { @@ -182,7 +182,7 @@ func TestRunTriggerRead(t *testing.T) { t.Run("when the run trigger ID is invalid", func(t *testing.T) { _, err := client.RunTriggers.Read(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for run trigger ID") + assert.Equal(t, err, ErrInvalidRunTriggerID) }) } @@ -217,6 +217,6 @@ func TestRunTriggerDelete(t *testing.T) { t.Run("when the run trigger ID is invalid", func(t *testing.T) { err := client.RunTriggers.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for run trigger ID") + assert.Equal(t, err, ErrInvalidRunTriggerID) }) } diff --git a/ssh_key.go b/ssh_key.go index 6b7fc530e..efaec7a97 100644 --- a/ssh_key.go +++ b/ssh_key.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -95,7 +94,7 @@ func (o SSHKeyCreateOptions) valid() error { return ErrRequiredName } if !validString(o.Value) { - return errors.New("value is required") + return ErrRequiredValue } return nil } @@ -128,7 +127,7 @@ func (s *sshKeys) Create(ctx context.Context, organization string, options SSHKe // Read an SSH key by its ID. func (s *sshKeys) Read(ctx context.Context, sshKeyID string) (*SSHKey, error) { if !validStringID(&sshKeyID) { - return nil, errors.New("invalid value for SSH key ID") + return nil, ErrInvalidSHHKeyID } u := fmt.Sprintf("ssh-keys/%s", url.QueryEscape(sshKeyID)) @@ -158,7 +157,7 @@ type SSHKeyUpdateOptions struct { // Update an SSH key by its ID. func (s *sshKeys) Update(ctx context.Context, sshKeyID string, options SSHKeyUpdateOptions) (*SSHKey, error) { if !validStringID(&sshKeyID) { - return nil, errors.New("invalid value for SSH key ID") + return nil, ErrInvalidSHHKeyID } // Make sure we don't send a user provided ID. @@ -182,7 +181,7 @@ func (s *sshKeys) Update(ctx context.Context, sshKeyID string, options SSHKeyUpd // Delete an SSH key by its ID. func (s *sshKeys) Delete(ctx context.Context, sshKeyID string) error { if !validStringID(&sshKeyID) { - return errors.New("invalid value for SSH key ID") + return ErrInvalidSHHKeyID } u := fmt.Sprintf("ssh-keys/%s", url.QueryEscape(sshKeyID)) diff --git a/ssh_key_integration_test.go b/ssh_key_integration_test.go index dd556c9be..eb0e65be8 100644 --- a/ssh_key_integration_test.go +++ b/ssh_key_integration_test.go @@ -100,7 +100,7 @@ func TestSSHKeysCreate(t *testing.T) { Name: String(randomString(t)), }) assert.Nil(t, k) - assert.EqualError(t, err, "value is required") + assert.Equal(t, err, ErrRequiredValue) }) t.Run("when options has an invalid organization", func(t *testing.T) { @@ -137,7 +137,7 @@ func TestSSHKeysRead(t *testing.T) { t.Run("without a valid SSH key ID", func(t *testing.T) { k, err := client.SSHKeys.Read(ctx, badIdentifier) assert.Nil(t, k) - assert.EqualError(t, err, "invalid value for SSH key ID") + assert.Equal(t, err, ErrInvalidSHHKeyID) }) } @@ -177,7 +177,7 @@ func TestSSHKeysUpdate(t *testing.T) { t.Run("without a valid SSH key ID", func(t *testing.T) { w, err := client.SSHKeys.Update(ctx, badIdentifier, SSHKeyUpdateOptions{}) assert.Nil(t, w) - assert.EqualError(t, err, "invalid value for SSH key ID") + assert.Equal(t, err, ErrInvalidSHHKeyID) }) } @@ -206,6 +206,6 @@ func TestSSHKeysDelete(t *testing.T) { t.Run("when the SSH key ID is invalid", func(t *testing.T) { err := client.SSHKeys.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for SSH key ID") + assert.Equal(t, err, ErrInvalidSHHKeyID) }) } diff --git a/state_version.go b/state_version.go index 31db07ed6..1397f954f 100644 --- a/state_version.go +++ b/state_version.go @@ -3,7 +3,6 @@ package tfe import ( "bytes" "context" - "errors" "fmt" "net/url" "time" @@ -78,10 +77,10 @@ type StateVersionListOptions struct { //check that StateVersionListOptions fields had valid values func (o StateVersionListOptions) valid() error { if !validString(&o.Organization) { - return errors.New("organization is required") + return ErrRequiredOrg } if !validString(&o.Workspace) { - return errors.New("workspace is required") + return ErrRequiredWorkspace } return nil } @@ -89,7 +88,7 @@ func (o StateVersionListOptions) valid() error { // List all the state versions for a given workspace. func (s *stateVersions) List(ctx context.Context, options *StateVersionListOptions) (*StateVersionList, error) { if options == nil { - return nil, errors.New("StateVersionListOptions is required") + return nil, ErrRequiredStateVerListOps } if err := options.valid(); err != nil { @@ -140,13 +139,13 @@ type StateVersionCreateOptions struct { func (o StateVersionCreateOptions) valid() error { if !validString(o.MD5) { - return errors.New("MD5 is required") + return ErrRequiredM5 } if o.Serial == nil { - return errors.New("serial is required") + return ErrRequiredSerial } if !validString(o.State) { - return errors.New("state is required") + return ErrRequiredState } return nil } @@ -194,7 +193,7 @@ type StateVersionReadOptions struct { // Read a state version by its ID. func (s *stateVersions) ReadWithOptions(ctx context.Context, svID string, options *StateVersionReadOptions) (*StateVersion, error) { if !validStringID(&svID) { - return nil, errors.New("invalid value for state version ID") + return nil, ErrInvalidStateVerID } u := fmt.Sprintf("state-versions/%s", url.QueryEscape(svID)) @@ -280,7 +279,7 @@ type StateVersionOutputsListOptions struct { // Outputs retrieves all the outputs of a state version by its ID. func (s *stateVersions) Outputs(ctx context.Context, svID string, options *StateVersionOutputsListOptions) (*StateVersionOutputsList, error) { if !validStringID(&svID) { - return nil, errors.New("invalid value for state version ID") + return nil, ErrInvalidStateVerID } u := fmt.Sprintf("state-versions/%s/outputs", url.QueryEscape(svID)) diff --git a/state_version_integration_test.go b/state_version_integration_test.go index 19b41a572..a5d524808 100644 --- a/state_version_integration_test.go +++ b/state_version_integration_test.go @@ -34,7 +34,7 @@ func TestStateVersionsList(t *testing.T) { t.Run("without StateVersionListOptions", func(t *testing.T) { svl, err := client.StateVersions.List(ctx, nil) assert.Nil(t, svl) - assert.EqualError(t, err, "StateVersionListOptions is required") + assert.Equal(t, err, ErrRequiredStateVerListOps) }) t.Run("without list options", func(t *testing.T) { @@ -96,7 +96,7 @@ func TestStateVersionsList(t *testing.T) { svl, err := client.StateVersions.List(ctx, options) assert.Nil(t, svl) - assert.EqualError(t, err, "organization is required") + assert.Equal(t, err, ErrRequiredOrg) }) t.Run("without a workspace", func(t *testing.T) { @@ -106,7 +106,7 @@ func TestStateVersionsList(t *testing.T) { svl, err := client.StateVersions.List(ctx, options) assert.Nil(t, svl) - assert.EqualError(t, err, "workspace is required") + assert.Equal(t, err, ErrRequiredWorkspace) }) } @@ -240,7 +240,7 @@ func TestStateVersionsCreate(t *testing.T) { State: String(base64.StdEncoding.EncodeToString(state)), }) assert.Nil(t, sv) - assert.EqualError(t, err, "MD5 is required") + assert.Equal(t, err, ErrRequiredM5) }) t.Run("withous serial", func(t *testing.T) { @@ -249,7 +249,7 @@ func TestStateVersionsCreate(t *testing.T) { State: String(base64.StdEncoding.EncodeToString(state)), }) assert.Nil(t, sv) - assert.EqualError(t, err, "serial is required") + assert.Equal(t, err, ErrRequiredSerial) }) t.Run("without state", func(t *testing.T) { @@ -258,7 +258,7 @@ func TestStateVersionsCreate(t *testing.T) { Serial: Int64(0), }) assert.Nil(t, sv) - assert.EqualError(t, err, "state is required") + assert.Equal(t, err, ErrRequiredState) }) t.Run("with invalid workspace id", func(t *testing.T) { @@ -301,7 +301,7 @@ func TestStateVersionsRead(t *testing.T) { t.Run("with invalid state version id", func(t *testing.T) { sv, err := client.StateVersions.Read(ctx, badIdentifier) assert.Nil(t, sv) - assert.EqualError(t, err, "invalid value for state version ID") + assert.Equal(t, err, ErrInvalidStateVerID) }) } diff --git a/team.go b/team.go index 738d85782..d093087a7 100644 --- a/team.go +++ b/team.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -170,7 +169,7 @@ func (s *teams) Create(ctx context.Context, organization string, options TeamCre // Read a single team by its ID. func (s *teams) Read(ctx context.Context, teamID string) (*Team, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } u := fmt.Sprintf("teams/%s", url.QueryEscape(teamID)) @@ -209,7 +208,7 @@ type TeamUpdateOptions struct { // Update a team by its ID. func (s *teams) Update(ctx context.Context, teamID string, options TeamUpdateOptions) (*Team, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } u := fmt.Sprintf("teams/%s", url.QueryEscape(teamID)) @@ -230,7 +229,7 @@ func (s *teams) Update(ctx context.Context, teamID string, options TeamUpdateOpt // Delete a team by its ID. func (s *teams) Delete(ctx context.Context, teamID string) error { if !validStringID(&teamID) { - return errors.New("invalid value for team ID") + return ErrInvalidTeamID } u := fmt.Sprintf("teams/%s", url.QueryEscape(teamID)) diff --git a/team_access.go b/team_access.go index fe787d2a7..00549f979 100644 --- a/team_access.go +++ b/team_access.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -110,7 +109,7 @@ type TeamAccessListOptions struct { //check that workspaceID field has a valid value func (o TeamAccessListOptions) valid() error { if !validString(&o.WorkspaceID) { - return errors.New("workspace ID is required") + return ErrRequiredWorkspaceID } if !validStringID(&o.WorkspaceID) { return ErrInvalidWorkspaceID @@ -121,7 +120,7 @@ func (o TeamAccessListOptions) valid() error { // List all the team accesses for a given workspace. func (s *teamAccesses) List(ctx context.Context, options *TeamAccessListOptions) (*TeamAccessList, error) { if options == nil { - return nil, errors.New("TeamAccessListOptions is required") + return nil, ErrRequireTeamAccessListOps } if err := options.valid(); err != nil { @@ -170,13 +169,13 @@ type TeamAccessAddOptions struct { func (o TeamAccessAddOptions) valid() error { if o.Access == nil { - return errors.New("access is required") + return ErrRequiredAccess } if o.Team == nil { - return errors.New("team is required") + return ErrRequiredTeam } if o.Workspace == nil { - return errors.New("workspace is required") + return ErrRequiredWorkspace } return nil } @@ -204,7 +203,7 @@ func (s *teamAccesses) Add(ctx context.Context, options TeamAccessAddOptions) (* // Read a team access by its ID. func (s *teamAccesses) Read(ctx context.Context, teamAccessID string) (*TeamAccess, error) { if !validStringID(&teamAccessID) { - return nil, errors.New("invalid value for team access ID") + return nil, ErrInvalidAccessTeamID } u := fmt.Sprintf("team-workspaces/%s", url.QueryEscape(teamAccessID)) @@ -245,7 +244,7 @@ type TeamAccessUpdateOptions struct { // Update team access for a workspace func (s *teamAccesses) Update(ctx context.Context, teamAccessID string, options TeamAccessUpdateOptions) (*TeamAccess, error) { if !validStringID(&teamAccessID) { - return nil, errors.New("invalid value for team access ID") + return nil, ErrInvalidAccessTeamID } u := fmt.Sprintf("team-workspaces/%s", url.QueryEscape(teamAccessID)) @@ -266,7 +265,7 @@ func (s *teamAccesses) Update(ctx context.Context, teamAccessID string, options // Remove team access from a workspace. func (s *teamAccesses) Remove(ctx context.Context, teamAccessID string) error { if !validStringID(&teamAccessID) { - return errors.New("invalid value for team access ID") + return ErrInvalidAccessTeamID } u := fmt.Sprintf("team-workspaces/%s", url.QueryEscape(teamAccessID)) diff --git a/team_access_integration_test.go b/team_access_integration_test.go index cc2c90381..52cdd6c69 100644 --- a/team_access_integration_test.go +++ b/team_access_integration_test.go @@ -66,7 +66,7 @@ func TestTeamAccessesList(t *testing.T) { t.Run("without TeamAccessListOptions", func(t *testing.T) { tal, err := client.TeamAccess.List(ctx, nil) assert.Nil(t, tal) - assert.EqualError(t, err, "TeamAccessListOptions is required") + assert.Equal(t, err, ErrRequireTeamAccessListOps) }) t.Run("without WorkspaceID options", func(t *testing.T) { @@ -77,7 +77,7 @@ func TestTeamAccessesList(t *testing.T) { }, }) assert.Nil(t, tal) - assert.EqualError(t, err, "workspace ID is required") + assert.Equal(t, err, ErrRequiredWorkspaceID) }) t.Run("without a valid workspaceID", func(t *testing.T) { @@ -199,7 +199,7 @@ func TestTeamAccessesAdd(t *testing.T) { Workspace: wTest, }) assert.Nil(t, ta) - assert.EqualError(t, err, "access is required") + assert.Equal(t, err, ErrRequiredAccess) }) t.Run("when options is missing team", func(t *testing.T) { @@ -208,7 +208,7 @@ func TestTeamAccessesAdd(t *testing.T) { Workspace: wTest, }) assert.Nil(t, ta) - assert.EqualError(t, err, "team is required") + assert.Equal(t, err, ErrRequiredTeam) }) t.Run("when options is missing workspace", func(t *testing.T) { @@ -217,7 +217,7 @@ func TestTeamAccessesAdd(t *testing.T) { Team: tmTest, }) assert.Nil(t, ta) - assert.EqualError(t, err, "workspace is required") + assert.Equal(t, err, ErrRequiredWorkspace) }) } @@ -269,7 +269,7 @@ func TestTeamAccessesRead(t *testing.T) { t.Run("without a valid team access ID", func(t *testing.T) { ta, err := client.TeamAccess.Read(ctx, badIdentifier) assert.Nil(t, ta) - assert.EqualError(t, err, "invalid value for team access ID") + assert.Equal(t, err, ErrInvalidAccessTeamID) }) } @@ -335,6 +335,6 @@ func TestTeamAccessesRemove(t *testing.T) { t.Run("when the team access ID is invalid", func(t *testing.T) { err := client.TeamAccess.Remove(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for team access ID") + assert.Equal(t, err, ErrInvalidAccessTeamID) }) } diff --git a/team_integration_test.go b/team_integration_test.go index e67f93962..ce92130d6 100644 --- a/team_integration_test.go +++ b/team_integration_test.go @@ -160,7 +160,7 @@ func TestTeamsRead(t *testing.T) { t.Run("without a valid team ID", func(t *testing.T) { tm, err := client.Teams.Read(ctx, badIdentifier) assert.Nil(t, tm) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } @@ -238,7 +238,7 @@ func TestTeamsUpdate(t *testing.T) { t.Run("without a valid team ID", func(t *testing.T) { tm, err := client.Teams.Update(ctx, badIdentifier, TeamUpdateOptions{}) assert.Nil(t, tm) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } @@ -264,7 +264,7 @@ func TestTeamsDelete(t *testing.T) { t.Run("without valid team ID", func(t *testing.T) { err := client.Teams.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } diff --git a/team_member.go b/team_member.go index 0708908c5..ece660fe9 100644 --- a/team_member.go +++ b/team_member.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" @@ -57,7 +56,7 @@ func (s *teamMembers) List(ctx context.Context, teamID string) ([]*User, error) // ListUsers returns the Users of this team. func (s *teamMembers) ListUsers(ctx context.Context, teamID string) ([]*User, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } options := struct { @@ -84,7 +83,7 @@ func (s *teamMembers) ListUsers(ctx context.Context, teamID string) ([]*User, er // ListOrganizationMemberships returns the OrganizationMemberships of this team. func (s *teamMembers) ListOrganizationMemberships(ctx context.Context, teamID string) ([]*OrganizationMembership, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } options := struct { @@ -117,16 +116,16 @@ type TeamMemberAddOptions struct { func (o *TeamMemberAddOptions) valid() error { if o.Usernames == nil && o.OrganizationMembershipIDs == nil { - return errors.New("usernames or organization membership ids are required") + return ErrRequiredUsernameOrMembershipIds } if o.Usernames != nil && o.OrganizationMembershipIDs != nil { - return errors.New("only one of usernames or organization membership ids can be provided") + return ErrRequiredOnlyOneField } if o.Usernames != nil && len(o.Usernames) == 0 { - return errors.New("invalid value for usernames") + return ErrInvalidUsernames } if o.OrganizationMembershipIDs != nil && len(o.OrganizationMembershipIDs) == 0 { - return errors.New("invalid value for organization membership ids") + return ErrInvalidMembershipIDs } return nil } @@ -143,7 +142,7 @@ func (o *TeamMemberAddOptions) kind() string { // Add multiple users to a team. func (s *teamMembers) Add(ctx context.Context, teamID string, options TeamMemberAddOptions) error { if !validStringID(&teamID) { - return errors.New("invalid value for team ID") + return ErrInvalidTeamID } if err := options.valid(); err != nil { return err @@ -188,16 +187,16 @@ type TeamMemberRemoveOptions struct { func (o *TeamMemberRemoveOptions) valid() error { if o.Usernames == nil && o.OrganizationMembershipIDs == nil { - return errors.New("usernames or organization membership ids are required") + return ErrRequiredUsernameOrMembershipIds } if o.Usernames != nil && o.OrganizationMembershipIDs != nil { - return errors.New("only one of usernames or organization membership ids can be provided") + return ErrRequiredOnlyOneField } if o.Usernames != nil && len(o.Usernames) == 0 { - return errors.New("invalid value for usernames") + return ErrInvalidUsernames } if o.OrganizationMembershipIDs != nil && len(o.OrganizationMembershipIDs) == 0 { - return errors.New("invalid value for organization membership ids") + return ErrInvalidMembershipIDs } return nil } @@ -214,7 +213,7 @@ func (o *TeamMemberRemoveOptions) kind() string { // Remove multiple users from a team. func (s *teamMembers) Remove(ctx context.Context, teamID string, options TeamMemberRemoveOptions) error { if !validStringID(&teamID) { - return errors.New("invalid value for team ID") + return ErrInvalidTeamID } if err := options.valid(); err != nil { return err diff --git a/team_member_integration_test.go b/team_member_integration_test.go index 1f5979c2f..ffa66332e 100644 --- a/team_member_integration_test.go +++ b/team_member_integration_test.go @@ -52,7 +52,7 @@ func TestTeamMembersList(t *testing.T) { t.Run("when the team ID is invalid", func(t *testing.T) { users, err := client.TeamMembers.List(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) assert.Nil(t, users) }) } @@ -68,7 +68,7 @@ func TestTeamMembersAddWithInvalidOptions(t *testing.T) { t.Run("when options is missing usernames and organization membership ids", func(t *testing.T) { err := client.TeamMembers.Add(ctx, tmTest.ID, TeamMemberAddOptions{}) - assert.EqualError(t, err, "usernames or organization membership ids are required") + assert.Equal(t, err, ErrRequiredUsernameOrMembershipIds) }) t.Run("when options has both usernames and organization membership ids", func(t *testing.T) { @@ -76,28 +76,28 @@ func TestTeamMembersAddWithInvalidOptions(t *testing.T) { Usernames: []string{}, OrganizationMembershipIDs: []string{}, }) - assert.EqualError(t, err, "only one of usernames or organization membership ids can be provided") + assert.Equal(t, err, ErrRequiredOnlyOneField) }) t.Run("when usernames is empty", func(t *testing.T) { err := client.TeamMembers.Add(ctx, tmTest.ID, TeamMemberAddOptions{ Usernames: []string{}, }) - assert.EqualError(t, err, "invalid value for usernames") + assert.Equal(t, err, ErrInvalidUsernames) }) t.Run("when organization membership ids is empty", func(t *testing.T) { err := client.TeamMembers.Add(ctx, tmTest.ID, TeamMemberAddOptions{ OrganizationMembershipIDs: []string{}, }) - assert.EqualError(t, err, "invalid value for organization membership ids") + assert.Equal(t, err, ErrInvalidMembershipIDs) }) t.Run("when the team ID is invalid", func(t *testing.T) { err := client.TeamMembers.Add(ctx, badIdentifier, TeamMemberAddOptions{ Usernames: []string{"user1"}, }) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } @@ -184,7 +184,7 @@ func TestTeamMembersRemoveWithInvalidOptions(t *testing.T) { t.Run("when options is missing usernames and organization membership ids", func(t *testing.T) { err := client.TeamMembers.Remove(ctx, tmTest.ID, TeamMemberRemoveOptions{}) - assert.EqualError(t, err, "usernames or organization membership ids are required") + assert.Equal(t, err, ErrRequiredUsernameOrMembershipIds) }) t.Run("when options has both usernames and organization membership ids", func(t *testing.T) { @@ -192,28 +192,28 @@ func TestTeamMembersRemoveWithInvalidOptions(t *testing.T) { Usernames: []string{}, OrganizationMembershipIDs: []string{}, }) - assert.EqualError(t, err, "only one of usernames or organization membership ids can be provided") + assert.Equal(t, err, ErrRequiredOnlyOneField) }) t.Run("when usernames is empty", func(t *testing.T) { err := client.TeamMembers.Remove(ctx, tmTest.ID, TeamMemberRemoveOptions{ Usernames: []string{}, }) - assert.EqualError(t, err, "invalid value for usernames") + assert.Equal(t, err, ErrInvalidUsernames) }) t.Run("when organization membership ids is empty", func(t *testing.T) { err := client.TeamMembers.Remove(ctx, tmTest.ID, TeamMemberRemoveOptions{ OrganizationMembershipIDs: []string{}, }) - assert.EqualError(t, err, "invalid value for organization membership ids") + assert.Equal(t, err, ErrInvalidMembershipIDs) }) t.Run("when the team ID is invalid", func(t *testing.T) { err := client.TeamMembers.Remove(ctx, badIdentifier, TeamMemberRemoveOptions{ Usernames: []string{"user1"}, }) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } diff --git a/team_token.go b/team_token.go index ac412c6bb..a624b9c8c 100644 --- a/team_token.go +++ b/team_token.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -44,7 +43,7 @@ type TeamToken struct { // Generate a new team token, replacing any existing token. func (s *teamTokens) Generate(ctx context.Context, teamID string) (*TeamToken, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } u := fmt.Sprintf("teams/%s/authentication-token", url.QueryEscape(teamID)) @@ -65,7 +64,7 @@ func (s *teamTokens) Generate(ctx context.Context, teamID string) (*TeamToken, e // Read a team token by its ID. func (s *teamTokens) Read(ctx context.Context, teamID string) (*TeamToken, error) { if !validStringID(&teamID) { - return nil, errors.New("invalid value for team ID") + return nil, ErrInvalidTeamID } u := fmt.Sprintf("teams/%s/authentication-token", url.QueryEscape(teamID)) @@ -86,7 +85,7 @@ func (s *teamTokens) Read(ctx context.Context, teamID string) (*TeamToken, error // Delete a team token by its ID. func (s *teamTokens) Delete(ctx context.Context, teamID string) error { if !validStringID(&teamID) { - return errors.New("invalid value for team ID") + return ErrInvalidTeamID } u := fmt.Sprintf("teams/%s/authentication-token", url.QueryEscape(teamID)) diff --git a/team_token_integration_test.go b/team_token_integration_test.go index acf5f6910..d1a22ab1d 100644 --- a/team_token_integration_test.go +++ b/team_token_integration_test.go @@ -38,7 +38,7 @@ func TestTeamTokensGenerate(t *testing.T) { t.Run("without valid team ID", func(t *testing.T) { tt, err := client.TeamTokens.Generate(ctx, badIdentifier) assert.Nil(t, tt) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } func TestTeamTokensRead(t *testing.T) { @@ -96,6 +96,6 @@ func TestTeamTokensDelete(t *testing.T) { t.Run("without valid team ID", func(t *testing.T) { err := client.TeamTokens.Delete(ctx, badIdentifier) - assert.EqualError(t, err, "invalid value for team ID") + assert.Equal(t, err, ErrInvalidTeamID) }) } diff --git a/tfe.go b/tfe.go index 2bcd2be41..4502393d2 100644 --- a/tfe.go +++ b/tfe.go @@ -7,7 +7,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "io" "math/rand" @@ -557,18 +556,17 @@ func serializeRequestBody(v interface{}) (interface{}, error) { // json-api library doesn't support serializing other things. var modelType reflect.Type bodyType := reflect.TypeOf(v) - invalidBodyError := errors.New("go-tfe bug: DELETE/PATCH/POST body must be nil, ptr, or ptr slice") switch bodyType.Kind() { case reflect.Slice: sliceElem := bodyType.Elem() if sliceElem.Kind() != reflect.Ptr { - return nil, invalidBodyError + return nil, ErrInvalidRequestBody } modelType = sliceElem.Elem() case reflect.Ptr: modelType = reflect.ValueOf(v).Elem().Type() default: - return nil, invalidBodyError + return nil, ErrInvalidRequestBody } // Infer whether the request uses jsonapi or regular json @@ -589,7 +587,7 @@ func serializeRequestBody(v interface{}) (interface{}, error) { // make sense, because a struct can only be serialized // as one or another. If this does happen, it's a bug // in the library that should be fixed at development time - return nil, errors.New("go-tfe bug: struct can't use both json and jsonapi attributes") + return nil, ErrInvalidStructFormat } if jsonFields > 0 { diff --git a/tfe_integration_test.go b/tfe_integration_test.go index a2965bb99..8c3873686 100644 --- a/tfe_integration_test.go +++ b/tfe_integration_test.go @@ -322,7 +322,7 @@ func TestClient_requestBodySerialization(t *testing.T) { t.Run("invalid struct request", func(t *testing.T) { body := InvalidBody{} _, _, err := createRequest(&body) - if err == nil || err.Error() != "go-tfe bug: struct can't use both json and jsonapi attributes" { + if err == nil || err != ErrInvalidStructFormat { t.Fatalf("unexpected error: %v", err) } }) diff --git a/user_token.go b/user_token.go index 6a0ad7480..bea041820 100644 --- a/user_token.go +++ b/user_token.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" "time" @@ -59,7 +58,7 @@ type UserTokenGenerateOptions struct { // Generate a new user token func (s *userTokens) Generate(ctx context.Context, userID string, options UserTokenGenerateOptions) (*UserToken, error) { if !validStringID(&userID) { - return nil, errors.New("invalid value for user ID") + return nil, ErrInvalidUserID } u := fmt.Sprintf("users/%s/authentication-tokens", url.QueryEscape(userID)) @@ -80,7 +79,7 @@ func (s *userTokens) Generate(ctx context.Context, userID string, options UserTo // List shows existing user tokens func (s *userTokens) List(ctx context.Context, userID string) (*UserTokenList, error) { if !validStringID(&userID) { - return nil, errors.New("invalid value for user ID") + return nil, ErrInvalidUserID } u := fmt.Sprintf("users/%s/authentication-tokens", url.QueryEscape(userID)) @@ -101,7 +100,7 @@ func (s *userTokens) List(ctx context.Context, userID string) (*UserTokenList, e // Read a user token by its ID. func (s *userTokens) Read(ctx context.Context, tokenID string) (*UserToken, error) { if !validStringID(&tokenID) { - return nil, errors.New("invalid value for token ID") + return nil, ErrInvalidTokenID } u := fmt.Sprintf("authentication-tokens/%s", url.QueryEscape(tokenID)) @@ -122,7 +121,7 @@ func (s *userTokens) Read(ctx context.Context, tokenID string) (*UserToken, erro // Delete a user token by its ID. func (s *userTokens) Delete(ctx context.Context, tokenID string) error { if !validStringID(&tokenID) { - return errors.New("invalid value for token ID") + return ErrInvalidTokenID } u := fmt.Sprintf("authentication-tokens/%s", url.QueryEscape(tokenID)) diff --git a/variable.go b/variable.go index 8638c54dc..2300bba6a 100644 --- a/variable.go +++ b/variable.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "net/url" ) @@ -121,10 +120,10 @@ type VariableCreateOptions struct { func (o VariableCreateOptions) valid() error { if !validString(o.Key) { - return errors.New("key is required") + return ErrRequiredKey } if o.Category == nil { - return errors.New("category is required") + return ErrRequiredCategory } return nil } @@ -159,7 +158,7 @@ func (s *variables) Read(ctx context.Context, workspaceID string, variableID str return nil, ErrInvalidWorkspaceID } if !validStringID(&variableID) { - return nil, errors.New("invalid value for variable ID") + return nil, ErrInvalidVariableID } u := fmt.Sprintf("workspaces/%s/vars/%s", url.QueryEscape(workspaceID), url.QueryEscape(variableID)) @@ -207,7 +206,7 @@ func (s *variables) Update(ctx context.Context, workspaceID string, variableID s return nil, ErrInvalidWorkspaceID } if !validStringID(&variableID) { - return nil, errors.New("invalid value for variable ID") + return nil, ErrInvalidVariableID } u := fmt.Sprintf("workspaces/%s/vars/%s", url.QueryEscape(workspaceID), url.QueryEscape(variableID)) @@ -231,7 +230,7 @@ func (s *variables) Delete(ctx context.Context, workspaceID string, variableID s return ErrInvalidWorkspaceID } if !validStringID(&variableID) { - return errors.New("invalid value for variable ID") + return ErrInvalidVariableID } u := fmt.Sprintf("workspaces/%s/vars/%s", url.QueryEscape(workspaceID), url.QueryEscape(variableID)) diff --git a/variable_integration_test.go b/variable_integration_test.go index 96e8be68a..1393c0a9c 100644 --- a/variable_integration_test.go +++ b/variable_integration_test.go @@ -158,7 +158,7 @@ func TestVariablesCreate(t *testing.T) { } _, err := client.Variables.Create(ctx, wTest.ID, options) - assert.EqualError(t, err, "key is required") + assert.Equal(t, err, ErrRequiredKey) }) t.Run("when options has an empty key", func(t *testing.T) { @@ -169,7 +169,7 @@ func TestVariablesCreate(t *testing.T) { } _, err := client.Variables.Create(ctx, wTest.ID, options) - assert.EqualError(t, err, "key is required") + assert.Equal(t, err, ErrRequiredKey) }) t.Run("when options is missing category", func(t *testing.T) { @@ -179,7 +179,7 @@ func TestVariablesCreate(t *testing.T) { } _, err := client.Variables.Create(ctx, wTest.ID, options) - assert.EqualError(t, err, "category is required") + assert.Equal(t, err, ErrRequiredCategory) }) t.Run("when workspace ID is invalid", func(t *testing.T) { @@ -227,7 +227,7 @@ func TestVariablesRead(t *testing.T) { t.Run("without a valid variable ID", func(t *testing.T) { v, err := client.Variables.Read(ctx, vTest.Workspace.ID, badIdentifier) assert.Nil(t, v) - assert.EqualError(t, err, "invalid value for variable ID") + assert.Equal(t, err, ErrInvalidVariableID) }) } @@ -295,7 +295,7 @@ func TestVariablesUpdate(t *testing.T) { t.Run("with invalid variable ID", func(t *testing.T) { _, err := client.Variables.Update(ctx, vTest.Workspace.ID, badIdentifier, VariableUpdateOptions{}) - assert.EqualError(t, err, "invalid value for variable ID") + assert.Equal(t, err, ErrInvalidVariableID) }) } @@ -325,6 +325,6 @@ func TestVariablesDelete(t *testing.T) { t.Run("with invalid variable ID", func(t *testing.T) { err := client.Variables.Delete(ctx, wTest.ID, badIdentifier) - assert.EqualError(t, err, "invalid value for variable ID") + assert.Equal(t, err, ErrInvalidVariableID) }) } diff --git a/workspace.go b/workspace.go index 534776fdb..9f75daa33 100644 --- a/workspace.go +++ b/workspace.go @@ -2,7 +2,6 @@ package tfe import ( "context" - "errors" "fmt" "io" "net/url" @@ -376,13 +375,13 @@ func (o WorkspaceCreateOptions) valid() error { return ErrInvalidName } if o.Operations != nil && o.ExecutionMode != nil { - return errors.New("operations is deprecated and cannot be specified when execution mode is used") + return ErrUnsupportedOperations } if o.AgentPoolID != nil && (o.ExecutionMode == nil || *o.ExecutionMode != "agent") { - return errors.New("specifying an agent pool ID requires 'agent' execution mode") + return ErrRequiredAgentMode } if o.AgentPoolID == nil && (o.ExecutionMode != nil && *o.ExecutionMode == "agent") { - return errors.New("'agent' execution mode requires an agent pool ID to be specified") + return ErrRequiredAgentPoolID } return nil @@ -591,10 +590,10 @@ func (o WorkspaceUpdateOptions) valid() error { return ErrInvalidName } if o.Operations != nil && o.ExecutionMode != nil { - return errors.New("operations is deprecated and cannot be specified when execution mode is used") + return ErrUnsupportedOperations } if o.AgentPoolID == nil && (o.ExecutionMode != nil && *o.ExecutionMode == "agent") { - return errors.New("'agent' execution mode requires an agent pool ID to be specified") + return ErrRequiredAgentPoolID } return nil @@ -830,10 +829,10 @@ type WorkspaceAssignSSHKeyOptions struct { func (o WorkspaceAssignSSHKeyOptions) valid() error { if !validString(o.SSHKeyID) { - return errors.New("SSH key ID is required") + return ErrRequiredSHHKeyID } if !validStringID(o.SSHKeyID) { - return errors.New("invalid value for SSH key ID") + return ErrInvalidSHHKeyID } return nil } diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 1a8845bf1..d1a7ac195 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -244,7 +244,7 @@ func TestWorkspacesCreate(t *testing.T) { w, err := client.Workspaces.Create(ctx, orgTest.Name, options) assert.Nil(t, w) - assert.EqualError(t, err, "operations is deprecated and cannot be specified when execution mode is used") + assert.Equal(t, err, ErrUnsupportedOperations) }) t.Run("when an agent pool ID is specified without 'agent' execution mode", func(t *testing.T) { @@ -255,7 +255,7 @@ func TestWorkspacesCreate(t *testing.T) { w, err := client.Workspaces.Create(ctx, orgTest.Name, options) assert.Nil(t, w) - assert.EqualError(t, err, "specifying an agent pool ID requires 'agent' execution mode") + assert.Equal(t, err, ErrRequiredAgentMode) }) t.Run("when 'agent' execution mode is specified without an an agent pool ID", func(t *testing.T) { @@ -266,7 +266,7 @@ func TestWorkspacesCreate(t *testing.T) { w, err := client.Workspaces.Create(ctx, orgTest.Name, options) assert.Nil(t, w) - assert.EqualError(t, err, "'agent' execution mode requires an agent pool ID to be specified") + assert.Equal(t, err, ErrRequiredAgentPoolID) }) t.Run("when an error is returned from the API", func(t *testing.T) { @@ -547,7 +547,7 @@ func TestWorkspacesUpdate(t *testing.T) { wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, options) assert.Nil(t, wAfter) - assert.EqualError(t, err, "operations is deprecated and cannot be specified when execution mode is used") + assert.Equal(t, err, ErrUnsupportedOperations) }) t.Run("when 'agent' execution mode is specified without an an agent pool ID", func(t *testing.T) { @@ -557,7 +557,7 @@ func TestWorkspacesUpdate(t *testing.T) { wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, options) assert.Nil(t, wAfter) - assert.EqualError(t, err, "'agent' execution mode requires an agent pool ID to be specified") + assert.Equal(t, err, ErrRequiredAgentPoolID) }) t.Run("when an error is returned from the api", func(t *testing.T) { @@ -887,7 +887,7 @@ func TestWorkspacesAssignSSHKey(t *testing.T) { t.Run("without an SSH key ID", func(t *testing.T) { w, err := client.Workspaces.AssignSSHKey(ctx, wTest.ID, WorkspaceAssignSSHKeyOptions{}) assert.Nil(t, w) - assert.EqualError(t, err, "SSH key ID is required") + assert.Equal(t, err, ErrRequiredSHHKeyID) }) t.Run("without a valid SSH key ID", func(t *testing.T) { @@ -895,7 +895,7 @@ func TestWorkspacesAssignSSHKey(t *testing.T) { SSHKeyID: String(badIdentifier), }) assert.Nil(t, w) - assert.EqualError(t, err, "invalid value for SSH key ID") + assert.Equal(t, err, ErrInvalidSHHKeyID) }) t.Run("without a valid workspace ID", func(t *testing.T) {