Skip to content

chore: add acceptance tests to user data source #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/data-sources/user.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ An existing user on the coder deployment

### Read-Only

- `avatar_url` (String) URL of the user's avatar.
- `created_at` (Number) Unix timestamp of when the user was created.
- `email` (String) Email of the user.
- `last_seen_at` (Number) Unix timestamp of when the user was last seen.
- `login_type` (String) Type of login for the user. Valid types are 'none', 'password', 'github', and 'oidc'.
- `name` (String) Display name of the user. Defaults to username.
- `name` (String) Display name of the user.
- `organization_ids` (Set of String) IDs of organizations the user is associated with.
- `roles` (Set of String) Roles assigned to the user. Valid roles are 'owner', 'template-admin', 'user-admin', and 'auditor'.
- `suspended` (Boolean) Whether the user is suspended.
Expand Down
9 changes: 4 additions & 5 deletions integration/user-test/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ data "coderd_user" "ethan" {
}

resource "coderd_user" "ethan2" {
username = "${data.coderd_user.ethan.username}2"
name = "${data.coderd_user.ethan.name}2"
email = "${data.coderd_user.ethan.email}.au"
roles = data.coderd_user.ethan.roles
username = "${data.coderd_user.ethan.username}2"
name = "${data.coderd_user.ethan.name}2"
email = "${data.coderd_user.ethan.email}.au"
roles = data.coderd_user.ethan.roles
suspended = data.coderd_user.ethan.suspended
}

7 changes: 7 additions & 0 deletions internal/provider/user_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ func (d *UserDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
resp.Diagnostics.AddError("Client Error", "User is not associated with any organizations")
return
}
if !data.ID.IsNull() && user.ID.String() != data.ID.ValueString() {
resp.Diagnostics.AddError("Client Error", "Retrieved User's ID does not match the provided ID")
return
} else if !data.Username.IsNull() && user.Username != data.Username.ValueString() {
resp.Diagnostics.AddError("Client Error", "Retrieved User's username does not match the provided username")
return
}

data.ID = types.StringValue(user.ID.String())
data.Username = types.StringValue(user.Username)
Expand Down
144 changes: 98 additions & 46 deletions internal/provider/user_data_source_test.go
Original file line number Diff line number Diff line change
@@ -1,66 +1,119 @@
package provider

/*
import (
"context"
"html/template"
"os"
"regexp"
"strings"
"testing"

"github.com/coder/coder/v2/codersdk"
"github.com/coder/terraform-provider-coderd/integration"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/stretchr/testify/require"
)

func TestAccUserDataSource(t *testing.T) {
// User by Username
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccUserDataSourceConfig{
Username: "example",
}.String(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("coderd_user.test", "username", "example"),
resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User"),
resource.TestCheckResourceAttr("coderd_user.test", "email", "[email protected]"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.#", "2"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.0", "auditor"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.1", "owner"),
resource.TestCheckResourceAttr("coderd_user.test", "login_type", "password"),
resource.TestCheckResourceAttr("coderd_user.test", "password", "SomeSecurePassword!"),
resource.TestCheckResourceAttr("coderd_user.test", "suspended", "false"),
),
if os.Getenv("TF_ACC") == "" {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what resource.Test does when it's run, so we should skip the setup if there's nothing to run.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write all these tests a bit nicer as several steps inside a resource.TestCase, but we're not really doing seperate steps, so subtests are fine.

t.Skip("Acceptance tests are disabled.")
}
ctx := context.Background()
client := integration.StartCoder(ctx, t, "user_data_acc")
firstUser, err := client.User(ctx, codersdk.Me)
require.NoError(t, err)
user, err := client.CreateUser(ctx, codersdk.CreateUserRequest{
Email: "[email protected]",
Username: "example",
Password: "SomeSecurePassword!",
UserLoginType: "password",
OrganizationID: firstUser.OrganizationIDs[0],
})
require.NoError(t, err)
_, err = client.UpdateUserRoles(ctx, user.Username, codersdk.UpdateRoles{
Roles: []string{"auditor"},
})
require.NoError(t, err)
_, err = client.UpdateUserProfile(ctx, user.Username, codersdk.UpdateUserProfileRequest{
Username: user.Username,
Name: "Example User",
})
require.NoError(t, err)
t.Run("UserByUsername", func(t *testing.T) {
cfg := testAccUserDataSourceConfig{
URL: client.URL.String(),
Token: client.SessionToken(),
Username: user.Username,
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: cfg.String(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.coderd_user.test", "username", "example"),
resource.TestCheckResourceAttr("data.coderd_user.test", "name", "Example User"),
resource.TestCheckResourceAttr("data.coderd_user.test", "email", "[email protected]"),
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.#", "1"),
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.0", "auditor"),
resource.TestCheckResourceAttr("data.coderd_user.test", "login_type", "password"),
resource.TestCheckResourceAttr("data.coderd_user.test", "suspended", "false"),
),
},
},
},
})
})
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
// User by ID
Steps: []resource.TestStep{
{
Config: testAccUserDataSourceConfig{
ID: "example",
}.String(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("coderd_user.test", "username", "example"),
resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User"),
resource.TestCheckResourceAttr("coderd_user.test", "email", "[email protected]"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.#", "2"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.0", "auditor"),
resource.TestCheckResourceAttr("coderd_user.test", "roles.1", "owner"),
resource.TestCheckResourceAttr("coderd_user.test", "login_type", "password"),
resource.TestCheckResourceAttr("coderd_user.test", "password", "SomeSecurePassword!"),
resource.TestCheckResourceAttr("coderd_user.test", "suspended", "false"),
),

t.Run("UserByID", func(t *testing.T) {
cfg := testAccUserDataSourceConfig{
URL: client.URL.String(),
Token: client.SessionToken(),
ID: user.ID.String(),
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
// User by ID
Steps: []resource.TestStep{
{
Config: cfg.String(t),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.coderd_user.test", "username", "example"),
resource.TestCheckResourceAttr("data.coderd_user.test", "name", "Example User"),
resource.TestCheckResourceAttr("data.coderd_user.test", "email", "[email protected]"),
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.#", "1"),
resource.TestCheckResourceAttr("data.coderd_user.test", "roles.0", "auditor"),
resource.TestCheckResourceAttr("data.coderd_user.test", "login_type", "password"),
resource.TestCheckResourceAttr("data.coderd_user.test", "suspended", "false"),
),
},
},
})
})
t.Run("NeitherIDNorUsername", func(t *testing.T) {
cfg := testAccUserDataSourceConfig{
URL: client.URL.String(),
Token: client.SessionToken(),
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
// Neither ID nor Username
Steps: []resource.TestStep{
{
Config: cfg.String(t),
ExpectError: regexp.MustCompile(`At least one of these attributes must be configured: \[id,username\]`),
},
},
},
})
})

}

type testAccUserDataSourceConfig struct {
URL string
Token string
URL string
Token string

ID string
Username string
Expand Down Expand Up @@ -92,4 +145,3 @@ data "coderd_user" "test" {

return buf.String()
}
*/
4 changes: 4 additions & 0 deletions internal/provider/user_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package provider
import (
"context"
"fmt"
"os"
"strings"
"testing"
"text/template"
Expand All @@ -13,6 +14,9 @@ import (
)

func TestAccUserResource(t *testing.T) {
if os.Getenv("TF_ACC") == "" {
t.Skip("Acceptance tests are disabled.")
}
ctx := context.Background()
client := integration.StartCoder(ctx, t, "user_acc")

Expand Down
Loading