2022-01-20 13:46:51 +00:00
|
|
|
package coderd_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-04-22 20:27:55 +00:00
|
|
|
"fmt"
|
2022-01-25 01:09:39 +00:00
|
|
|
"net/http"
|
2022-01-20 13:46:51 +00:00
|
|
|
"testing"
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
"github.com/google/uuid"
|
2022-01-20 16:00:13 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2022-01-20 13:46:51 +00:00
|
|
|
"github.com/coder/coder/coderd/coderdtest"
|
2022-03-25 21:07:45 +00:00
|
|
|
"github.com/coder/coder/coderd/httpmw"
|
2022-02-06 00:24:51 +00:00
|
|
|
"github.com/coder/coder/codersdk"
|
2022-01-20 13:46:51 +00:00
|
|
|
)
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestFirstUser(t *testing.T) {
|
2022-02-10 14:33:27 +00:00
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("BadRequest", func(t *testing.T) {
|
2022-02-10 14:33:27 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.CreateFirstUser(context.Background(), codersdk.CreateFirstUserRequest{})
|
2022-03-07 17:40:54 +00:00
|
|
|
require.Error(t, err)
|
2022-02-10 14:33:27 +00:00
|
|
|
})
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("AlreadyExists", func(t *testing.T) {
|
2022-02-10 14:33:27 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.CreateFirstUser(context.Background(), codersdk.CreateFirstUserRequest{
|
2022-04-01 19:42:36 +00:00
|
|
|
Email: "some@email.com",
|
|
|
|
Username: "exampleuser",
|
|
|
|
Password: "password",
|
|
|
|
OrganizationName: "someorg",
|
2022-03-07 17:40:54 +00:00
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Create", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-02-10 14:33:27 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestPostLogin(t *testing.T) {
|
2022-01-20 13:46:51 +00:00
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("InvalidUser", func(t *testing.T) {
|
2022-01-20 13:46:51 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.LoginWithPassword(context.Background(), codersdk.LoginWithPasswordRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: "my@email.org",
|
|
|
|
Password: "password",
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
2022-01-20 13:46:51 +00:00
|
|
|
})
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("BadPassword", func(t *testing.T) {
|
2022-01-20 13:46:51 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
req := codersdk.CreateFirstUserRequest{
|
2022-04-01 19:42:36 +00:00
|
|
|
Email: "testuser@coder.com",
|
|
|
|
Username: "testuser",
|
|
|
|
Password: "testpass",
|
|
|
|
OrganizationName: "testorg",
|
2022-03-07 17:40:54 +00:00
|
|
|
}
|
|
|
|
_, err := client.CreateFirstUser(context.Background(), req)
|
|
|
|
require.NoError(t, err)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err = client.LoginWithPassword(context.Background(), codersdk.LoginWithPasswordRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: req.Email,
|
|
|
|
Password: "badpass",
|
2022-01-20 13:46:51 +00:00
|
|
|
})
|
2022-02-06 00:24:51 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
2022-01-20 13:46:51 +00:00
|
|
|
})
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("Success", func(t *testing.T) {
|
2022-01-24 17:07:42 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
req := codersdk.CreateFirstUserRequest{
|
2022-04-01 19:42:36 +00:00
|
|
|
Email: "testuser@coder.com",
|
|
|
|
Username: "testuser",
|
|
|
|
Password: "testpass",
|
|
|
|
OrganizationName: "testorg",
|
2022-03-07 17:40:54 +00:00
|
|
|
}
|
|
|
|
_, err := client.CreateFirstUser(context.Background(), req)
|
|
|
|
require.NoError(t, err)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err = client.LoginWithPassword(context.Background(), codersdk.LoginWithPasswordRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: req.Email,
|
|
|
|
Password: req.Password,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPostLogout(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
t.Run("ClearCookie", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
fullURL, err := client.URL.Parse("/api/v2/users/logout")
|
|
|
|
require.NoError(t, err, "Server URL should parse successfully")
|
|
|
|
|
|
|
|
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, fullURL.String(), nil)
|
|
|
|
require.NoError(t, err, "/logout request construction should succeed")
|
|
|
|
|
|
|
|
httpClient := &http.Client{}
|
|
|
|
|
|
|
|
response, err := httpClient.Do(req)
|
|
|
|
require.NoError(t, err, "/logout request should succeed")
|
|
|
|
response.Body.Close()
|
|
|
|
|
|
|
|
cookies := response.Cookies()
|
|
|
|
require.Len(t, cookies, 1, "Exactly one cookie should be returned")
|
|
|
|
|
|
|
|
require.Equal(t, cookies[0].Name, httpmw.AuthCookie, "Cookie should be the auth cookie")
|
|
|
|
require.Equal(t, cookies[0].MaxAge, -1, "Cookie should be set to delete")
|
2022-01-23 05:58:10 +00:00
|
|
|
})
|
2022-02-06 00:24:51 +00:00
|
|
|
}
|
2022-01-23 05:58:10 +00:00
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
func TestPostUsers(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("NoAuth", func(t *testing.T) {
|
2022-01-20 13:46:51 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{})
|
2022-01-20 13:46:51 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
})
|
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
t.Run("Conflicting", func(t *testing.T) {
|
2022-01-20 13:46:51 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
me, err := client.User(context.Background(), codersdk.Me)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err = client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: me.Email,
|
|
|
|
Username: me.Username,
|
|
|
|
Password: "password",
|
2022-04-01 19:42:36 +00:00
|
|
|
OrganizationID: uuid.New(),
|
2022-01-20 13:46:51 +00:00
|
|
|
})
|
2022-02-06 00:24:51 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
2022-01-20 13:46:51 +00:00
|
|
|
})
|
2022-01-23 05:58:10 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("OrganizationNotFound", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
2022-04-01 19:42:36 +00:00
|
|
|
OrganizationID: uuid.New(),
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: "another@user.org",
|
|
|
|
Username: "someone-else",
|
|
|
|
Password: "testing",
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("OrganizationNoAccess", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
first := coderdtest.CreateFirstUser(t, client)
|
|
|
|
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
|
2022-04-01 19:42:36 +00:00
|
|
|
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Name: "another",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err = client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Email: "some@domain.com",
|
|
|
|
Username: "anotheruser",
|
|
|
|
Password: "testing",
|
|
|
|
OrganizationID: org.ID,
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
t.Run("Create", func(t *testing.T) {
|
2022-01-23 05:58:10 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
2022-03-22 19:17:50 +00:00
|
|
|
_, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
OrganizationID: user.OrganizationID,
|
|
|
|
Email: "another@user.org",
|
|
|
|
Username: "someone-else",
|
|
|
|
Password: "testing",
|
2022-02-06 00:24:51 +00:00
|
|
|
})
|
2022-01-23 05:58:10 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
2022-02-06 00:24:51 +00:00
|
|
|
}
|
2022-01-25 19:52:58 +00:00
|
|
|
|
2022-04-12 14:05:21 +00:00
|
|
|
func TestUpdateUserProfile(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
t.Run("UserNotFound", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
|
|
|
_, err := client.UpdateUserProfile(context.Background(), uuid.New(), codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: "newusername",
|
|
|
|
Email: "newemail@coder.com",
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
// Right now, we are raising a BAD request error because we don't support a
|
|
|
|
// user accessing other users info
|
|
|
|
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ConflictingEmail", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
|
|
|
existentUser, _ := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
|
|
|
Email: "bruno@coder.com",
|
|
|
|
Username: "bruno",
|
|
|
|
Password: "password",
|
|
|
|
OrganizationID: user.OrganizationID,
|
|
|
|
})
|
|
|
|
_, err := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: "newusername",
|
|
|
|
Email: existentUser.Email,
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ConflictingUsername", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
|
|
|
existentUser, _ := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
|
|
|
Email: "bruno@coder.com",
|
|
|
|
Username: "bruno",
|
|
|
|
Password: "password",
|
|
|
|
OrganizationID: user.OrganizationID,
|
|
|
|
})
|
|
|
|
_, err := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: existentUser.Username,
|
|
|
|
Email: "newemail@coder.com",
|
|
|
|
})
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("UpdateUsernameAndEmail", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
|
|
|
userProfile, err := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: "newusername",
|
|
|
|
Email: "newemail@coder.com",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, userProfile.Username, "newusername")
|
|
|
|
require.Equal(t, userProfile.Email, "newemail@coder.com")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("UpdateUsername", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
|
|
|
me, _ := client.User(context.Background(), codersdk.Me)
|
|
|
|
userProfile, err := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: me.Username,
|
|
|
|
Email: "newemail@coder.com",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, userProfile.Username, me.Username)
|
|
|
|
require.Equal(t, userProfile.Email, "newemail@coder.com")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("KeepUserName", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
|
|
|
me, _ := client.User(context.Background(), codersdk.Me)
|
|
|
|
newName := "New Name"
|
|
|
|
firstProfile, _ := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: me.Username,
|
|
|
|
Email: me.Email,
|
|
|
|
Name: &newName,
|
|
|
|
})
|
|
|
|
t.Log(firstProfile)
|
|
|
|
userProfile, err := client.UpdateUserProfile(context.Background(), codersdk.Me, codersdk.UpdateUserProfileRequest{
|
|
|
|
Username: "newusername",
|
|
|
|
Email: "newemail@coder.com",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, userProfile.Username, "newusername")
|
|
|
|
require.Equal(t, userProfile.Email, "newemail@coder.com")
|
|
|
|
require.Equal(t, userProfile.Name, newName)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
func TestUserByName(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.User(context.Background(), codersdk.Me)
|
2022-02-06 00:24:51 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2022-04-18 17:19:47 +00:00
|
|
|
func TestGetUsers(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
|
|
|
client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
2022-04-22 20:27:55 +00:00
|
|
|
Email: "alice@email.com",
|
|
|
|
Username: "alice",
|
2022-04-18 17:19:47 +00:00
|
|
|
Password: "password",
|
|
|
|
OrganizationID: user.OrganizationID,
|
|
|
|
})
|
2022-04-22 20:27:55 +00:00
|
|
|
// No params is all users
|
|
|
|
users, err := client.Users(context.Background(), codersdk.UsersRequest{})
|
2022-04-18 17:19:47 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, users, 2)
|
|
|
|
}
|
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
func TestOrganizationsByUser(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
orgs, err := client.OrganizationsByUser(context.Background(), codersdk.Me)
|
2022-02-06 00:24:51 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, orgs)
|
|
|
|
require.Len(t, orgs, 1)
|
|
|
|
}
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestOrganizationByUserAndName(t *testing.T) {
|
2022-02-18 04:09:33 +00:00
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("NoExist", func(t *testing.T) {
|
2022-02-18 04:09:33 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.OrganizationByName(context.Background(), codersdk.Me, "nothing")
|
2022-03-07 17:40:54 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
|
|
|
})
|
2022-02-18 04:09:33 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("NoMember", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
first := coderdtest.CreateFirstUser(t, client)
|
|
|
|
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
|
2022-04-01 19:42:36 +00:00
|
|
|
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Name: "another",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err = client.OrganizationByName(context.Background(), codersdk.Me, org.Name)
|
2022-02-18 04:09:33 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("Valid", func(t *testing.T) {
|
2022-02-18 04:09:33 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
|
|
|
org, err := client.Organization(context.Background(), user.OrganizationID)
|
|
|
|
require.NoError(t, err)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err = client.OrganizationByName(context.Background(), codersdk.Me, org.Name)
|
2022-02-18 04:09:33 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestPostOrganizationsByUser(t *testing.T) {
|
2022-02-06 00:24:51 +00:00
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("Conflict", func(t *testing.T) {
|
2022-01-25 19:52:58 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
|
|
|
org, err := client.Organization(context.Background(), user.OrganizationID)
|
|
|
|
require.NoError(t, err)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err = client.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Name: org.Name,
|
2022-01-25 19:52:58 +00:00
|
|
|
})
|
2022-02-06 00:24:51 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
2022-02-06 00:24:51 +00:00
|
|
|
})
|
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("Create", func(t *testing.T) {
|
2022-02-06 00:24:51 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Name: "new",
|
2022-02-06 00:24:51 +00:00
|
|
|
})
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPostAPIKey(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
t.Run("InvalidUser", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
|
|
|
|
|
|
|
client.SessionToken = ""
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.CreateAPIKey(context.Background(), codersdk.Me)
|
2022-02-06 00:24:51 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
2022-01-25 19:52:58 +00:00
|
|
|
})
|
|
|
|
|
2022-02-06 00:24:51 +00:00
|
|
|
t.Run("Success", func(t *testing.T) {
|
2022-01-25 19:52:58 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
apiKey, err := client.CreateAPIKey(context.Background(), codersdk.Me)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NotNil(t, apiKey)
|
|
|
|
require.GreaterOrEqual(t, len(apiKey.Key), 2)
|
2022-02-06 00:24:51 +00:00
|
|
|
require.NoError(t, err)
|
2022-01-25 19:52:58 +00:00
|
|
|
})
|
2022-01-20 13:46:51 +00:00
|
|
|
}
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestPostWorkspacesByUser(t *testing.T) {
|
2022-01-25 01:09:39 +00:00
|
|
|
t.Parallel()
|
2022-04-06 17:42:40 +00:00
|
|
|
t.Run("InvalidTemplate", func(t *testing.T) {
|
2022-01-25 01:09:39 +00:00
|
|
|
t.Parallel()
|
2022-03-07 17:40:54 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
_ = coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
2022-04-06 17:42:40 +00:00
|
|
|
TemplateID: uuid.New(),
|
|
|
|
Name: "workspace",
|
2022-03-07 17:40:54 +00:00
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
|
|
|
})
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-04-06 17:42:40 +00:00
|
|
|
t.Run("NoTemplateAccess", func(t *testing.T) {
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Parallel()
|
2022-02-21 20:36:29 +00:00
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-07 17:40:54 +00:00
|
|
|
first := coderdtest.CreateFirstUser(t, client)
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
|
2022-04-01 19:42:36 +00:00
|
|
|
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
|
2022-03-07 17:40:54 +00:00
|
|
|
Name: "another",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
2022-04-06 17:42:40 +00:00
|
|
|
version := coderdtest.CreateTemplateVersion(t, other, org.ID, nil)
|
|
|
|
template := coderdtest.CreateTemplate(t, other, org.ID, version.ID)
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err = client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
2022-04-06 17:42:40 +00:00
|
|
|
TemplateID: template.ID,
|
|
|
|
Name: "workspace",
|
2022-03-07 17:40:54 +00:00
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
|
|
|
})
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("AlreadyExists", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
coderdtest.NewProvisionerDaemon(t, client)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
2022-04-06 17:42:40 +00:00
|
|
|
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
|
|
|
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
|
|
|
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
2022-04-06 17:42:40 +00:00
|
|
|
TemplateID: template.ID,
|
|
|
|
Name: workspace.Name,
|
2022-03-07 17:40:54 +00:00
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
|
|
|
})
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
t.Run("Create", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
coderdtest.NewProvisionerDaemon(t, client)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
2022-04-06 17:42:40 +00:00
|
|
|
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
|
|
|
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
|
|
|
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
2022-03-07 17:40:54 +00:00
|
|
|
})
|
|
|
|
}
|
2022-01-25 01:09:39 +00:00
|
|
|
|
2022-03-07 17:40:54 +00:00
|
|
|
func TestWorkspacesByUser(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
t.Run("ListEmpty", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.WorkspacesByUser(context.Background(), codersdk.Me)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("List", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
coderdtest.NewProvisionerDaemon(t, client)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
2022-04-06 17:42:40 +00:00
|
|
|
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
|
|
|
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
|
|
|
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
2022-04-01 19:42:36 +00:00
|
|
|
workspaces, err := client.WorkspacesByUser(context.Background(), codersdk.Me)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, workspaces, 1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestWorkspaceByUserAndName(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
t.Run("NotFound", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.WorkspaceByName(context.Background(), codersdk.Me, "something")
|
2022-03-07 17:40:54 +00:00
|
|
|
var apiErr *codersdk.Error
|
|
|
|
require.ErrorAs(t, err, &apiErr)
|
|
|
|
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
|
|
|
})
|
|
|
|
t.Run("Get", func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
client := coderdtest.New(t, nil)
|
2022-03-22 19:17:50 +00:00
|
|
|
coderdtest.NewProvisionerDaemon(t, client)
|
2022-03-07 17:40:54 +00:00
|
|
|
user := coderdtest.CreateFirstUser(t, client)
|
2022-04-06 17:42:40 +00:00
|
|
|
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
|
|
|
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
|
|
|
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
2022-04-01 19:42:36 +00:00
|
|
|
_, err := client.WorkspaceByName(context.Background(), codersdk.Me, workspace.Name)
|
2022-03-07 17:40:54 +00:00
|
|
|
require.NoError(t, err)
|
2022-01-25 01:09:39 +00:00
|
|
|
})
|
|
|
|
}
|
2022-04-22 20:27:55 +00:00
|
|
|
|
|
|
|
// TestPaginatedUsers creates a list of users, then tries to paginate through
|
|
|
|
// them using different page sizes.
|
|
|
|
func TestPaginatedUsers(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
|
|
client := coderdtest.New(t, &coderdtest.Options{APIRateLimit: -1})
|
|
|
|
coderdtest.CreateFirstUser(t, client)
|
|
|
|
me, err := client.User(context.Background(), codersdk.Me)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
allUsers := make([]codersdk.User, 0)
|
|
|
|
allUsers = append(allUsers, me)
|
|
|
|
specialUsers := make([]codersdk.User, 0)
|
|
|
|
|
|
|
|
org, err := client.CreateOrganization(ctx, me.ID, codersdk.CreateOrganizationRequest{
|
|
|
|
Name: "default",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// When 100 users exist
|
|
|
|
total := 100
|
|
|
|
// Create users
|
|
|
|
for i := 0; i < total; i++ {
|
|
|
|
email := fmt.Sprintf("%d@coder.com", i)
|
|
|
|
username := fmt.Sprintf("user%d", i)
|
|
|
|
if i%2 == 0 {
|
|
|
|
email = fmt.Sprintf("%d@gmail.com", i)
|
|
|
|
username = fmt.Sprintf("specialuser%d", i)
|
|
|
|
}
|
|
|
|
// One side effect of having to use the api vs the db calls directly, is you cannot
|
|
|
|
// mock time. Ideally I could pass in mocked times and space these users out.
|
|
|
|
//
|
|
|
|
// But this also serves as a good test. Postgres has microsecond precision on its timestamps.
|
|
|
|
// If 2 users share the same created_at, that could cause an issue if you are strictly paginating via
|
|
|
|
// timestamps. The pagination goes by timestamps and uuids.
|
|
|
|
newUser, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
|
|
|
|
Email: email,
|
|
|
|
Username: username,
|
|
|
|
Password: "password",
|
|
|
|
OrganizationID: org.ID,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
allUsers = append(allUsers, newUser)
|
|
|
|
if i%2 == 0 {
|
|
|
|
specialUsers = append(specialUsers, newUser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertPagination(ctx, t, client, 10, allUsers, nil)
|
|
|
|
assertPagination(ctx, t, client, 5, allUsers, nil)
|
|
|
|
assertPagination(ctx, t, client, 3, allUsers, nil)
|
|
|
|
assertPagination(ctx, t, client, 1, allUsers, nil)
|
|
|
|
|
|
|
|
// Try a search
|
|
|
|
gmailSearch := func(request codersdk.UsersRequest) codersdk.UsersRequest {
|
|
|
|
request.Search = "gmail"
|
|
|
|
return request
|
|
|
|
}
|
|
|
|
assertPagination(ctx, t, client, 3, specialUsers, gmailSearch)
|
|
|
|
assertPagination(ctx, t, client, 7, specialUsers, gmailSearch)
|
|
|
|
|
|
|
|
usernameSearch := func(request codersdk.UsersRequest) codersdk.UsersRequest {
|
|
|
|
request.Search = "specialuser"
|
|
|
|
return request
|
|
|
|
}
|
|
|
|
assertPagination(ctx, t, client, 3, specialUsers, usernameSearch)
|
|
|
|
assertPagination(ctx, t, client, 1, specialUsers, usernameSearch)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert pagination will page through the list of all users using the given
|
|
|
|
// limit for each page. The 'allUsers' is the expected full list to compare
|
|
|
|
// against.
|
|
|
|
func assertPagination(ctx context.Context, t *testing.T, client *codersdk.Client, limit int, allUsers []codersdk.User,
|
|
|
|
opt func(request codersdk.UsersRequest) codersdk.UsersRequest) {
|
|
|
|
var count int
|
|
|
|
if opt == nil {
|
|
|
|
opt = func(request codersdk.UsersRequest) codersdk.UsersRequest {
|
|
|
|
return request
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the first page
|
|
|
|
page, err := client.Users(ctx, opt(codersdk.UsersRequest{
|
|
|
|
Limit: limit,
|
|
|
|
}))
|
|
|
|
require.NoError(t, err, "first page")
|
|
|
|
require.Equalf(t, page, allUsers[:limit], "first page, limit=%d", limit)
|
|
|
|
count += len(page)
|
|
|
|
|
|
|
|
for {
|
|
|
|
if len(page) == 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
afterCursor := page[len(page)-1].ID
|
|
|
|
// Assert each page is the next expected page
|
|
|
|
// This is using a cursor, and only works if all users created_at
|
|
|
|
// is unique.
|
|
|
|
page, err = client.Users(ctx, opt(codersdk.UsersRequest{
|
|
|
|
Limit: limit,
|
|
|
|
AfterUser: afterCursor,
|
|
|
|
}))
|
|
|
|
require.NoError(t, err, "next cursor page")
|
|
|
|
|
|
|
|
// Also check page by offset
|
|
|
|
offsetPage, err := client.Users(ctx, opt(codersdk.UsersRequest{
|
|
|
|
Limit: limit,
|
|
|
|
Offset: count,
|
|
|
|
}))
|
|
|
|
require.NoError(t, err, "next offset page")
|
|
|
|
|
|
|
|
var expected []codersdk.User
|
|
|
|
if count+limit > len(allUsers) {
|
|
|
|
expected = allUsers[count:]
|
|
|
|
} else {
|
|
|
|
expected = allUsers[count : count+limit]
|
|
|
|
}
|
|
|
|
require.Equalf(t, page, expected, "next users, after=%s, limit=%d", afterCursor, limit)
|
|
|
|
require.Equalf(t, offsetPage, expected, "offset users, offset=%d, limit=%d", count, limit)
|
|
|
|
|
|
|
|
// Also check the before
|
|
|
|
prevPage, err := client.Users(ctx, opt(codersdk.UsersRequest{
|
|
|
|
Offset: count - limit,
|
|
|
|
Limit: limit,
|
|
|
|
}))
|
|
|
|
require.NoError(t, err, "prev page")
|
|
|
|
require.Equal(t, allUsers[count-limit:count], prevPage, "prev users")
|
|
|
|
count += len(page)
|
|
|
|
}
|
|
|
|
}
|