Skip to content

Commit 375a205

Browse files
chore: add acceptance tests to user data source (#23)
1 parent ee5c4e5 commit 375a205

File tree

5 files changed

+115
-52
lines changed

5 files changed

+115
-52
lines changed

docs/data-sources/user.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ An existing user on the coder deployment
2222

2323
### Read-Only
2424

25+
- `avatar_url` (String) URL of the user's avatar.
2526
- `created_at` (Number) Unix timestamp of when the user was created.
2627
- `email` (String) Email of the user.
2728
- `last_seen_at` (Number) Unix timestamp of when the user was last seen.
2829
- `login_type` (String) Type of login for the user. Valid types are 'none', 'password', 'github', and 'oidc'.
29-
- `name` (String) Display name of the user. Defaults to username.
30+
- `name` (String) Display name of the user.
3031
- `organization_ids` (Set of String) IDs of organizations the user is associated with.
3132
- `roles` (Set of String) Roles assigned to the user. Valid roles are 'owner', 'template-admin', 'user-admin', and 'auditor'.
3233
- `suspended` (Boolean) Whether the user is suspended.

integration/user-test/main.tf

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ data "coderd_user" "ethan" {
2222
}
2323

2424
resource "coderd_user" "ethan2" {
25-
username = "${data.coderd_user.ethan.username}2"
26-
name = "${data.coderd_user.ethan.name}2"
27-
email = "${data.coderd_user.ethan.email}.au"
28-
roles = data.coderd_user.ethan.roles
25+
username = "${data.coderd_user.ethan.username}2"
26+
name = "${data.coderd_user.ethan.name}2"
27+
email = "${data.coderd_user.ethan.email}.au"
28+
roles = data.coderd_user.ethan.roles
2929
suspended = data.coderd_user.ethan.suspended
3030
}
31-

internal/provider/user_data_source.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ func (d *UserDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
155155
resp.Diagnostics.AddError("Client Error", "User is not associated with any organizations")
156156
return
157157
}
158+
if !data.ID.IsNull() && user.ID.String() != data.ID.ValueString() {
159+
resp.Diagnostics.AddError("Client Error", "Retrieved User's ID does not match the provided ID")
160+
return
161+
} else if !data.Username.IsNull() && user.Username != data.Username.ValueString() {
162+
resp.Diagnostics.AddError("Client Error", "Retrieved User's username does not match the provided username")
163+
return
164+
}
158165

159166
data.ID = types.StringValue(user.ID.String())
160167
data.Username = types.StringValue(user.Username)

internal/provider/user_data_source_test.go

Lines changed: 98 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,119 @@
11
package provider
22

3-
/*
43
import (
4+
"context"
55
"html/template"
6+
"os"
7+
"regexp"
68
"strings"
79
"testing"
810

11+
"github.com/coder/coder/v2/codersdk"
12+
"github.com/coder/terraform-provider-coderd/integration"
913
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
14+
"github.com/stretchr/testify/require"
1015
)
1116

1217
func TestAccUserDataSource(t *testing.T) {
13-
// User by Username
14-
resource.Test(t, resource.TestCase{
15-
PreCheck: func() { testAccPreCheck(t) },
16-
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
17-
Steps: []resource.TestStep{
18-
{
19-
Config: testAccUserDataSourceConfig{
20-
Username: "example",
21-
}.String(t),
22-
Check: resource.ComposeAggregateTestCheckFunc(
23-
resource.TestCheckResourceAttr("coderd_user.test", "username", "example"),
24-
resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User"),
25-
resource.TestCheckResourceAttr("coderd_user.test", "email", "example@coder.com"),
26-
resource.TestCheckResourceAttr("coderd_user.test", "roles.#", "2"),
27-
resource.TestCheckResourceAttr("coderd_user.test", "roles.0", "auditor"),
28-
resource.TestCheckResourceAttr("coderd_user.test", "roles.1", "owner"),
29-
resource.TestCheckResourceAttr("coderd_user.test", "login_type", "password"),
30-
resource.TestCheckResourceAttr("coderd_user.test", "password", "SomeSecurePassword!"),
31-
resource.TestCheckResourceAttr("coderd_user.test", "suspended", "false"),
32-
),
18+
if os.Getenv("TF_ACC") == "" {
19+
t.Skip("Acceptance tests are disabled.")
20+
}
21+
ctx := context.Background()
22+
client := integration.StartCoder(ctx, t, "user_data_acc")
23+
firstUser, err := client.User(ctx, codersdk.Me)
24+
require.NoError(t, err)
25+
user, err := client.CreateUser(ctx, codersdk.CreateUserRequest{
26+
Email: "example@coder.com",
27+
Username: "example",
28+
Password: "SomeSecurePassword!",
29+
UserLoginType: "password",
30+
OrganizationID: firstUser.OrganizationIDs[0],
31+
})
32+
require.NoError(t, err)
33+
_, err = client.UpdateUserRoles(ctx, user.Username, codersdk.UpdateRoles{
34+
Roles: []string{"auditor"},
35+
})
36+
require.NoError(t, err)
37+
_, err = client.UpdateUserProfile(ctx, user.Username, codersdk.UpdateUserProfileRequest{
38+
Username: user.Username,
39+
Name: "Example User",
40+
})
41+
require.NoError(t, err)
42+
t.Run("UserByUsername", func(t *testing.T) {
43+
cfg := testAccUserDataSourceConfig{
44+
URL: client.URL.String(),
45+
Token: client.SessionToken(),
46+
Username: user.Username,
47+
}
48+
resource.Test(t, resource.TestCase{
49+
PreCheck: func() { testAccPreCheck(t) },
50+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
51+
Steps: []resource.TestStep{
52+
{
53+
Config: cfg.String(t),
54+
Check: resource.ComposeAggregateTestCheckFunc(
55+
resource.TestCheckResourceAttr("data.coderd_user.test", "username", "example"),
56+
resource.TestCheckResourceAttr("data.coderd_user.test", "name", "Example User"),
57+
resource.TestCheckResourceAttr("data.coderd_user.test", "email", "example@coder.com"),
58+
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.#", "1"),
59+
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.0", "auditor"),
60+
resource.TestCheckResourceAttr("data.coderd_user.test", "login_type", "password"),
61+
resource.TestCheckResourceAttr("data.coderd_user.test", "suspended", "false"),
62+
),
63+
},
3364
},
34-
},
65+
})
3566
})
36-
resource.Test(t, resource.TestCase{
37-
PreCheck: func() { testAccPreCheck(t) },
38-
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
39-
// User by ID
40-
Steps: []resource.TestStep{
41-
{
42-
Config: testAccUserDataSourceConfig{
43-
ID: "example",
44-
}.String(t),
45-
Check: resource.ComposeAggregateTestCheckFunc(
46-
resource.TestCheckResourceAttr("coderd_user.test", "username", "example"),
47-
resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User"),
48-
resource.TestCheckResourceAttr("coderd_user.test", "email", "example@coder.com"),
49-
resource.TestCheckResourceAttr("coderd_user.test", "roles.#", "2"),
50-
resource.TestCheckResourceAttr("coderd_user.test", "roles.0", "auditor"),
51-
resource.TestCheckResourceAttr("coderd_user.test", "roles.1", "owner"),
52-
resource.TestCheckResourceAttr("coderd_user.test", "login_type", "password"),
53-
resource.TestCheckResourceAttr("coderd_user.test", "password", "SomeSecurePassword!"),
54-
resource.TestCheckResourceAttr("coderd_user.test", "suspended", "false"),
55-
),
67+
68+
t.Run("UserByID", func(t *testing.T) {
69+
cfg := testAccUserDataSourceConfig{
70+
URL: client.URL.String(),
71+
Token: client.SessionToken(),
72+
ID: user.ID.String(),
73+
}
74+
resource.Test(t, resource.TestCase{
75+
PreCheck: func() { testAccPreCheck(t) },
76+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
77+
// User by ID
78+
Steps: []resource.TestStep{
79+
{
80+
Config: cfg.String(t),
81+
Check: resource.ComposeAggregateTestCheckFunc(
82+
resource.TestCheckResourceAttr("data.coderd_user.test", "username", "example"),
83+
resource.TestCheckResourceAttr("data.coderd_user.test", "name", "Example User"),
84+
resource.TestCheckResourceAttr("data.coderd_user.test", "email", "example@coder.com"),
85+
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.#", "1"),
86+
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.0", "auditor"),
87+
resource.TestCheckResourceAttr("data.coderd_user.test", "login_type", "password"),
88+
resource.TestCheckResourceAttr("data.coderd_user.test", "suspended", "false"),
89+
),
90+
},
91+
},
92+
})
93+
})
94+
t.Run("NeitherIDNorUsername", func(t *testing.T) {
95+
cfg := testAccUserDataSourceConfig{
96+
URL: client.URL.String(),
97+
Token: client.SessionToken(),
98+
}
99+
resource.Test(t, resource.TestCase{
100+
PreCheck: func() { testAccPreCheck(t) },
101+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
102+
// Neither ID nor Username
103+
Steps: []resource.TestStep{
104+
{
105+
Config: cfg.String(t),
106+
ExpectError: regexp.MustCompile(`At least one of these attributes must be configured: \[id,username\]`),
107+
},
56108
},
57-
},
109+
})
58110
})
111+
59112
}
60113

61114
type testAccUserDataSourceConfig struct {
62-
URL string
63-
Token string
115+
URL string
116+
Token string
64117

65118
ID string
66119
Username string
@@ -92,4 +145,3 @@ data "coderd_user" "test" {
92145

93146
return buf.String()
94147
}
95-
*/

internal/provider/user_resource_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package provider
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"strings"
78
"testing"
89
"text/template"
@@ -13,6 +14,9 @@ import (
1314
)
1415

1516
func TestAccUserResource(t *testing.T) {
17+
if os.Getenv("TF_ACC") == "" {
18+
t.Skip("Acceptance tests are disabled.")
19+
}
1620
ctx := context.Background()
1721
client := integration.StartCoder(ctx, t, "user_acc")
1822

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy