Skip to content

Commit c86bb33

Browse files
committed
acceptance test
1 parent dab2c45 commit c86bb33

File tree

6 files changed

+188
-37
lines changed

6 files changed

+188
-37
lines changed

integration/integration.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ func StartCoder(ctx context.Context, t *testing.T, name string) *codersdk.Client
7575

7676
// nolint:gosec // For testing only.
7777
var (
78-
testEmail = "testing@coder.com"
78+
testEmail = "admin@coder.com"
7979
testPassword = "InsecurePassw0rd!"
80-
testUsername = "testing"
80+
testUsername = "admin"
8181
)
8282

8383
// Perform first time setup
@@ -96,6 +96,7 @@ func StartCoder(ctx context.Context, t *testing.T, name string) *codersdk.Client
9696
Email: testEmail,
9797
Username: testUsername,
9898
Password: testPassword,
99+
Trial: true,
99100
})
100101
require.NoError(t, err, "create first user")
101102
resp, err := client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{

internal/provider/group_resource.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func (r *GroupResource) Schema(ctx context.Context, req resource.SchemaRequest,
5858
"id": schema.StringAttribute{
5959
MarkdownDescription: "Group ID.",
6060
Computed: true,
61+
PlanModifiers: []planmodifier.String{
62+
stringplanmodifier.UseStateForUnknown(),
63+
},
6164
},
6265
"name": schema.StringAttribute{
6366
MarkdownDescription: "The unique name of the group.",
@@ -145,7 +148,7 @@ func (r *GroupResource) Create(ctx context.Context, req resource.CreateRequest,
145148
Name: data.Name.ValueString(),
146149
DisplayName: displayName,
147150
AvatarURL: data.AvatarURL.ValueString(),
148-
QuotaAllowance: 0,
151+
QuotaAllowance: int(data.QuotaAllowance.ValueInt32()),
149152
})
150153
if err != nil {
151154
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create group, got error: %s", err))

internal/provider/group_resource_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,137 @@
44
package provider
55

66
import (
7+
"context"
8+
"strings"
79
"testing"
10+
"text/template"
11+
12+
"github.com/coder/coder/v2/codersdk"
13+
"github.com/coder/terraform-provider-coderd/integration"
14+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
15+
"github.com/stretchr/testify/require"
816
)
917

1018
func TestAccGroupResource(t *testing.T) {
19+
// if os.Getenv("TF_ACC") == "" {
20+
// t.Skip("Acceptance tests are disabled.")
21+
// }
22+
23+
ctx := context.Background()
24+
client := integration.StartCoder(ctx, t, "group_acc")
25+
firstUser, err := client.User(ctx, codersdk.Me)
26+
require.NoError(t, err)
27+
28+
user1, err := client.CreateUser(ctx, codersdk.CreateUserRequest{
29+
Email: "example@coder.com",
30+
Username: "example",
31+
Password: "SomeSecurePassword!",
32+
UserLoginType: "password",
33+
OrganizationID: firstUser.OrganizationIDs[0],
34+
})
35+
require.NoError(t, err)
36+
37+
user2, err := client.CreateUser(ctx, codersdk.CreateUserRequest{
38+
Email: "example2@coder.com",
39+
Username: "example2",
40+
Password: "SomeSecurePassword!",
41+
UserLoginType: "password",
42+
OrganizationID: firstUser.OrganizationIDs[0],
43+
})
44+
require.NoError(t, err)
45+
46+
cfg1 := testAccGroupResourceconfig{
47+
URL: client.URL.String(),
48+
Token: client.SessionToken(),
49+
Name: PtrTo("example-group"),
50+
DisplayName: PtrTo("Example Group"),
51+
AvatarUrl: PtrTo("https://google.com"),
52+
QuotaAllowance: PtrTo(int32(100)),
53+
OrganizationID: PtrTo(firstUser.OrganizationIDs[0].String()),
54+
Members: PtrTo([]string{user1.ID.String()}),
55+
}
56+
57+
cfg2 := cfg1
58+
cfg2.Name = PtrTo("example-group-new")
59+
cfg2.DisplayName = PtrTo("Example Group New")
60+
cfg2.Members = PtrTo([]string{user2.ID.String()})
61+
62+
resource.Test(t, resource.TestCase{
63+
IsUnitTest: true,
64+
PreCheck: func() { testAccPreCheck(t) },
65+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
66+
Steps: []resource.TestStep{
67+
// Create and Read
68+
{
69+
Config: cfg1.String(t),
70+
Check: resource.ComposeAggregateTestCheckFunc(
71+
resource.TestCheckResourceAttr("coderd_group.test", "name", "example-group"),
72+
resource.TestCheckResourceAttr("coderd_group.test", "display_name", "Example Group"),
73+
resource.TestCheckResourceAttr("coderd_group.test", "avatar_url", "https://google.com"),
74+
resource.TestCheckResourceAttr("coderd_group.test", "quota_allowance", "100"),
75+
resource.TestCheckResourceAttr("coderd_group.test", "organization_id", firstUser.OrganizationIDs[0].String()),
76+
resource.TestCheckResourceAttr("coderd_group.test", "members.#", "1"),
77+
resource.TestCheckResourceAttr("coderd_group.test", "members.0", user1.ID.String()),
78+
),
79+
},
80+
// Import
81+
{
82+
ResourceName: "coderd_group.test",
83+
ImportState: true,
84+
ImportStateVerify: true,
85+
},
86+
// Update and Read
87+
{
88+
Config: cfg2.String(t),
89+
Check: resource.ComposeAggregateTestCheckFunc(
90+
resource.TestCheckResourceAttr("coderd_group.test", "name", "example-group-new"),
91+
resource.TestCheckResourceAttr("coderd_group.test", "display_name", "Example Group New"),
92+
resource.TestCheckResourceAttr("coderd_group.test", "members.#", "1"),
93+
resource.TestCheckResourceAttr("coderd_group.test", "members.0", user2.ID.String()),
94+
),
95+
},
96+
},
97+
})
98+
}
99+
100+
type testAccGroupResourceconfig struct {
101+
URL string
102+
Token string
103+
104+
Name *string
105+
DisplayName *string
106+
AvatarUrl *string
107+
QuotaAllowance *int32
108+
OrganizationID *string
109+
Members *[]string
110+
}
111+
112+
func (c testAccGroupResourceconfig) String(t *testing.T) string {
113+
t.Helper()
114+
tpl := `
115+
provider coderd {
116+
url = "{{.URL}}"
117+
token = "{{.Token}}"
118+
}
119+
120+
resource "coderd_group" "test" {
121+
name = {{orNull .Name}}
122+
display_name = {{orNull .DisplayName}}
123+
avatar_url = {{orNull .AvatarUrl}}
124+
quota_allowance = {{orNull .QuotaAllowance}}
125+
organization_id = {{orNull .OrganizationID}}
126+
members = {{orNull .Members}}
127+
}
128+
`
129+
funcMap := template.FuncMap{
130+
"orNull": PrintOrNull(t),
131+
}
132+
133+
buf := strings.Builder{}
134+
tmpl, err := template.New("test").Funcs(funcMap).Parse(tpl)
135+
require.NoError(t, err)
11136

137+
err = tmpl.Execute(&buf, c)
138+
require.NoError(t, err)
139+
return buf.String()
12140
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func (p *CoderdProvider) Configure(ctx context.Context, req provider.ConfigureRe
104104
func (p *CoderdProvider) Resources(ctx context.Context) []func() resource.Resource {
105105
return []func() resource.Resource{
106106
NewUserResource,
107+
NewGroupResource,
107108
}
108109
}
109110

internal/provider/user_resource_test.go

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package provider
22

33
import (
44
"context"
5-
"fmt"
65
"os"
76
"strings"
87
"testing"
@@ -89,6 +88,7 @@ type testAccUserResourceConfig struct {
8988
}
9089

9190
func (c testAccUserResourceConfig) String(t *testing.T) string {
91+
t.Helper()
9292
tpl := `
9393
provider coderd {
9494
url = "{{.URL}}"
@@ -107,39 +107,7 @@ resource "coderd_user" "test" {
107107
`
108108
// Define template functions
109109
funcMap := template.FuncMap{
110-
"orNull": func(v interface{}) string {
111-
if v == nil {
112-
return "null"
113-
}
114-
switch value := v.(type) {
115-
case *string:
116-
if value == nil {
117-
return "null"
118-
}
119-
return fmt.Sprintf("%q", *value)
120-
case *bool:
121-
if value == nil {
122-
return "null"
123-
}
124-
return fmt.Sprintf(`%t`, *value)
125-
case *[]string:
126-
if value == nil {
127-
return "null"
128-
}
129-
var result string
130-
for i, role := range *value {
131-
if i > 0 {
132-
result += ", "
133-
}
134-
result += fmt.Sprintf("%q", role)
135-
}
136-
return fmt.Sprintf("[%s]", result)
137-
138-
default:
139-
require.NoError(t, fmt.Errorf("unknown type in template: %T", value))
140-
return ""
141-
}
142-
},
110+
"orNull": PrintOrNull(t),
143111
}
144112

145113
buf := strings.Builder{}

internal/provider/util.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
package provider
22

3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
310
func PtrTo[T any](v T) *T {
411
return &v
512
}
13+
14+
func PrintOrNull(t *testing.T) func(v any) string {
15+
return func(v any) string {
16+
t.Helper()
17+
if v == nil {
18+
return "null"
19+
}
20+
switch value := v.(type) {
21+
case *int32:
22+
if value == nil {
23+
return "null"
24+
}
25+
return fmt.Sprintf("%d", *value)
26+
case *string:
27+
if value == nil {
28+
return "null"
29+
}
30+
out := fmt.Sprintf("%q", *value)
31+
return out
32+
case *bool:
33+
if value == nil {
34+
return "null"
35+
}
36+
return fmt.Sprintf(`%t`, *value)
37+
case *[]string:
38+
if value == nil {
39+
return "null"
40+
}
41+
var result string
42+
for i, role := range *value {
43+
if i > 0 {
44+
result += ", "
45+
}
46+
result += fmt.Sprintf("%q", role)
47+
}
48+
return fmt.Sprintf("[%s]", result)
49+
50+
default:
51+
require.NoError(t, fmt.Errorf("unknown type in template: %T", value))
52+
return ""
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)