diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md index 88c9a1f..2b12670 100644 --- a/docs/data-sources/user.md +++ b/docs/data-sources/user.md @@ -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. diff --git a/integration/user-test/main.tf b/integration/user-test/main.tf index 46cb6f6..83bd655 100644 --- a/integration/user-test/main.tf +++ b/integration/user-test/main.tf @@ -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 } - diff --git a/internal/provider/user_data_source.go b/internal/provider/user_data_source.go index 8254fe1..a8654ce 100644 --- a/internal/provider/user_data_source.go +++ b/internal/provider/user_data_source.go @@ -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) diff --git a/internal/provider/user_data_source_test.go b/internal/provider/user_data_source_test.go index 6c5c0df..b3e3987 100644 --- a/internal/provider/user_data_source_test.go +++ b/internal/provider/user_data_source_test.go @@ -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", "example@coder.com"), - 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") == "" { + 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: "example@coder.com", + 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", "example@coder.com"), + 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", "example@coder.com"), - 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", "example@coder.com"), + 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 @@ -92,4 +145,3 @@ data "coderd_user" "test" { return buf.String() } -*/ diff --git a/internal/provider/user_resource_test.go b/internal/provider/user_resource_test.go index c95ace0..f955310 100644 --- a/internal/provider/user_resource_test.go +++ b/internal/provider/user_resource_test.go @@ -3,6 +3,7 @@ package provider import ( "context" "fmt" + "os" "strings" "testing" "text/template" @@ -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") 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