From 2840903693a7960c7b87a277f3bb6e2d14bd2c83 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Wed, 27 Nov 2024 02:44:06 +0000 Subject: [PATCH 1/2] fix: mark invalid UUIDs as known --- internal/provider/uuid.go | 20 ++++++++++---------- internal/provider/uuid_internal_test.go | 10 +++++++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/internal/provider/uuid.go b/internal/provider/uuid.go index 8cd8912..ac37b04 100644 --- a/internal/provider/uuid.go +++ b/internal/provider/uuid.go @@ -48,16 +48,16 @@ func (t uuidType) ValueFromString(ctx context.Context, in basetypes.StringValue) return NewUUIDUnknown(), diags } - value, err := uuid.Parse(in.ValueString()) - if err != nil { - // The framework doesn't want us to return validation errors here - // for some reason. They get caught by `ValidateAttribute` instead, - // and this function isn't called directly by our provider - UUIDValue - // takes a valid UUID instead of a string. - return NewUUIDUnknown(), diags - } - - return UUIDValue(value), diags + // This function deliberately does not handle invalid UUIDs. + // Instead, `ValidateAttribute` will be called + // on the stored string during `validate` `plan` and `apply`, + // which will also create an error diagnostic. + // For that reason, storing the zero UUID is fine. + v, _ := uuid.Parse(in.ValueString()) + return UUID{ + StringValue: in, + value: v, + }, diags } // ValueFromTerraform implements basetypes.StringTypable. diff --git a/internal/provider/uuid_internal_test.go b/internal/provider/uuid_internal_test.go index 6283bb9..697d9c3 100644 --- a/internal/provider/uuid_internal_test.go +++ b/internal/provider/uuid_internal_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" "github.com/stretchr/testify/require" ) @@ -37,9 +38,12 @@ func TestUUIDTypeValueFromTerraform(t *testing.T) { expected: UUIDValue(ValidUUID), }, { - name: "invalid UUID", - input: tftypes.NewValue(tftypes.String, "invalid"), - expected: NewUUIDUnknown(), + name: "invalid UUID", + input: tftypes.NewValue(tftypes.String, "invalid"), + expected: UUID{ + StringValue: basetypes.NewStringValue("invalid"), + value: uuid.Nil, + }, }, } From 2fe148d8a8f8d78dfbc33034150d9a47cf0a42e9 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Wed, 27 Nov 2024 02:50:41 +0000 Subject: [PATCH 2/2] test --- internal/provider/user_data_source_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/internal/provider/user_data_source_test.go b/internal/provider/user_data_source_test.go index ebdab83..6a9309f 100644 --- a/internal/provider/user_data_source_test.go +++ b/internal/provider/user_data_source_test.go @@ -57,6 +57,7 @@ func TestAccUserDataSource(t *testing.T) { Username: ptr.Ref(user.Username), } resource.Test(t, resource.TestCase{ + IsUnitTest: true, PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ @@ -75,6 +76,7 @@ func TestAccUserDataSource(t *testing.T) { ID: ptr.Ref(user.ID.String()), } resource.Test(t, resource.TestCase{ + IsUnitTest: true, PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, // User by ID @@ -92,6 +94,7 @@ func TestAccUserDataSource(t *testing.T) { Token: client.SessionToken(), } resource.Test(t, resource.TestCase{ + IsUnitTest: true, PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, // Neither ID nor Username @@ -104,6 +107,24 @@ func TestAccUserDataSource(t *testing.T) { }) }) + t.Run("InvalidUUIDError", func(t *testing.T) { + cfg := testAccUserDataSourceConfig{ + URL: client.URL.String(), + Token: client.SessionToken(), + ID: ptr.Ref("invalid-uuid"), + } + resource.Test(t, resource.TestCase{ + IsUnitTest: true, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: cfg.String(t), + ExpectError: regexp.MustCompile(`The provided value cannot be parsed as a UUID`), + }, + }, + }) + }) } type testAccUserDataSourceConfig struct {