Skip to content

Commit 4a02d81

Browse files
committed
idiomatic tests and review notes
1 parent 8f03598 commit 4a02d81

File tree

2 files changed

+74
-67
lines changed

2 files changed

+74
-67
lines changed

provider/workspace_preset.go

+14-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
77
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
89
"github.com/mitchellh/mapstructure"
910
)
1011

@@ -31,12 +32,11 @@ func workspacePresetDataSource() *schema.Resource {
3132
return diag.Errorf("decode workspace preset: %s", err)
3233
}
3334

34-
if preset.Name == "" {
35-
return diag.Errorf("workspace preset name must be set")
36-
}
37-
35+
// MinItems doesn't work with maps, so we need to check the length
36+
// of the map manually. All other validation is handled by the
37+
// schema.
3838
if len(preset.Parameters) == 0 {
39-
return diag.Errorf("workspace preset must define a value for at least one parameter")
39+
return diag.Errorf("expected \"parameters\" to not be an empty map")
4040
}
4141

4242
rd.SetId(preset.Name)
@@ -50,14 +50,20 @@ func workspacePresetDataSource() *schema.Resource {
5050
Computed: true,
5151
},
5252
"name": {
53-
Type: schema.TypeString,
54-
Description: "Name of the workspace preset.",
55-
Required: true,
53+
Type: schema.TypeString,
54+
Description: "Name of the workspace preset.",
55+
Required: true,
56+
ValidateFunc: validation.StringIsNotEmpty,
5657
},
5758
"parameters": {
5859
Type: schema.TypeMap,
5960
Description: "Parameters of the workspace preset.",
6061
Required: true,
62+
Elem: &schema.Schema{
63+
Type: schema.TypeString,
64+
Required: true,
65+
ValidateFunc: validation.StringIsNotEmpty,
66+
},
6167
},
6268
},
6369
}

provider/workspace_preset_test.go

+60-59
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ import (
1010
)
1111

1212
func TestWorkspacePreset(t *testing.T) {
13-
// Happy Path:
14-
resource.Test(t, resource.TestCase{
15-
ProviderFactories: coderFactory(),
16-
IsUnitTest: true,
17-
Steps: []resource.TestStep{{
13+
t.Parallel()
14+
type testcase struct {
15+
Name string
16+
Config string
17+
ExpectError *regexp.Regexp
18+
Check func(state *terraform.State) error
19+
}
20+
testcases := []testcase{
21+
{
22+
Name: "Happy Path",
1823
Config: `
1924
data "coder_workspace_preset" "preset_1" {
2025
name = "preset_1"
@@ -32,96 +37,92 @@ func TestWorkspacePreset(t *testing.T) {
3237
require.Equal(t, attrs["parameters.region"], "us-east1-a")
3338
return nil
3439
},
35-
}},
36-
})
37-
38-
// Given the Name field is not provided
39-
resource.Test(t, resource.TestCase{
40-
ProviderFactories: coderFactory(),
41-
IsUnitTest: true,
42-
Steps: []resource.TestStep{{
40+
},
41+
{
42+
Name: "Name field is not provided",
4343
Config: `
4444
data "coder_workspace_preset" "preset_1" {
4545
parameters = {
4646
"region" = "us-east1-a"
4747
}
4848
}`,
49-
// This is from terraform's validation based on our schema, not based on our validation in ReadContext:
49+
// This validation is done by Terraform, but it could still break if we misconfigure the schema.
50+
// So we test it here to make sure we don't regress.
5051
ExpectError: regexp.MustCompile("The argument \"name\" is required, but no definition was found"),
51-
}},
52-
})
53-
54-
// Given the Name field is empty
55-
resource.Test(t, resource.TestCase{
56-
ProviderFactories: coderFactory(),
57-
IsUnitTest: true,
58-
Steps: []resource.TestStep{{
52+
},
53+
{
54+
Name: "Name field is empty",
5955
Config: `
6056
data "coder_workspace_preset" "preset_1" {
6157
name = ""
6258
parameters = {
6359
"region" = "us-east1-a"
6460
}
6561
}`,
66-
ExpectError: regexp.MustCompile("workspace preset name must be set"),
67-
}},
68-
})
69-
70-
// Given the Name field is not a string
71-
resource.Test(t, resource.TestCase{
72-
ProviderFactories: coderFactory(),
73-
IsUnitTest: true,
74-
Steps: []resource.TestStep{{
62+
// This validation is done by Terraform, but it could still break if we misconfigure the schema.
63+
// So we test it here to make sure we don't regress.
64+
ExpectError: regexp.MustCompile("expected \"name\" to not be an empty string"),
65+
},
66+
{
67+
Name: "Name field is not a string",
7568
Config: `
7669
data "coder_workspace_preset" "preset_1" {
7770
name = [1, 2, 3]
7871
parameters = {
7972
"region" = "us-east1-a"
8073
}
8174
}`,
75+
// This validation is done by Terraform, but it could still break if we misconfigure the schema.
76+
// So we test it here to make sure we don't regress.
8277
ExpectError: regexp.MustCompile("Incorrect attribute value type"),
83-
}},
84-
})
85-
86-
// Given the Parameters field is not provided
87-
resource.Test(t, resource.TestCase{
88-
ProviderFactories: coderFactory(),
89-
IsUnitTest: true,
90-
Steps: []resource.TestStep{{
78+
},
79+
{
80+
Name: "Parameters field is not provided",
9181
Config: `
9282
data "coder_workspace_preset" "preset_1" {
9383
name = "preset_1"
9484
}`,
85+
// This validation is done by Terraform, but it could still break if we misconfigure the schema.
86+
// So we test it here to make sure we don't regress.
9587
ExpectError: regexp.MustCompile("The argument \"parameters\" is required, but no definition was found"),
96-
}},
97-
})
98-
99-
// Given the Parameters field is empty
100-
resource.Test(t, resource.TestCase{
101-
ProviderFactories: coderFactory(),
102-
IsUnitTest: true,
103-
Steps: []resource.TestStep{{
88+
},
89+
{
90+
Name: "Parameters field is empty",
10491
Config: `
10592
data "coder_workspace_preset" "preset_1" {
10693
name = "preset_1"
10794
parameters = {}
10895
}`,
109-
ExpectError: regexp.MustCompile("workspace preset must define a value for at least one parameter"),
110-
}},
111-
})
112-
113-
// Given the Parameters field is not a map
114-
resource.Test(t, resource.TestCase{
115-
ProviderFactories: coderFactory(),
116-
IsUnitTest: true,
117-
Steps: []resource.TestStep{{
96+
// This validation is *not* done by Terraform, because MinItems doesn't work with maps.
97+
// We've implemented the validation in ReadContext, so we test it here to make sure we don't regress.
98+
ExpectError: regexp.MustCompile("expected \"parameters\" to not be an empty map"),
99+
},
100+
{
101+
Name: "Parameters field is not a map",
118102
Config: `
119103
data "coder_workspace_preset" "preset_1" {
120104
name = "preset_1"
121105
parameters = "not a map"
122106
}`,
123-
// This is from terraform's validation based on our schema, not based on our validation in ReadContext:
107+
// This validation is done by Terraform, but it could still break if we misconfigure the schema.
108+
// So we test it here to make sure we don't regress.
124109
ExpectError: regexp.MustCompile("Inappropriate value for attribute \"parameters\": map of string required"),
125-
}},
126-
})
110+
},
111+
}
112+
113+
for _, testcase := range testcases {
114+
t.Run(testcase.Name, func(t *testing.T) {
115+
t.Parallel()
116+
117+
resource.Test(t, resource.TestCase{
118+
ProviderFactories: coderFactory(),
119+
IsUnitTest: true,
120+
Steps: []resource.TestStep{{
121+
Config: testcase.Config,
122+
ExpectError: testcase.ExpectError,
123+
Check: testcase.Check,
124+
}},
125+
})
126+
})
127+
}
127128
}

0 commit comments

Comments
 (0)