Files
coder/enterprise/cli/create_test.go
Steven Masley 5c977c6be7 chore: rename 'first-organization' to 'coder' (#14808)
Rename the first-organization original name. Users can change from the
original name.
2024-09-26 13:20:44 -05:00

208 lines
5.9 KiB
Go

package cli_test
import (
"context"
"fmt"
"sync"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license"
"github.com/coder/coder/v2/pty/ptytest"
)
func TestEnterpriseCreate(t *testing.T) {
t.Parallel()
type setupData struct {
firstResponse codersdk.CreateFirstUserResponse
second codersdk.Organization
owner *codersdk.Client
member *codersdk.Client
}
type setupArgs struct {
firstTemplates []string
secondTemplates []string
}
// setupMultipleOrganizations creates an extra organization, assigns a member
// both organizations, and optionally creates templates in each organization.
setupMultipleOrganizations := func(t *testing.T, args setupArgs) setupData {
dv := coderdtest.DeploymentValues(t)
dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)}
ownerClient, first := coderdenttest.New(t, &coderdenttest.Options{
Options: &coderdtest.Options{
DeploymentValues: dv,
// This only affects the first org.
IncludeProvisionerDaemon: true,
},
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
codersdk.FeatureMultipleOrganizations: 1,
},
},
})
second := coderdenttest.CreateOrganization(t, ownerClient, coderdenttest.CreateOrganizationOptions{
IncludeProvisionerDaemon: true,
})
member, _ := coderdtest.CreateAnotherUser(t, ownerClient, first.OrganizationID, rbac.ScopedRoleOrgMember(second.ID))
var wg sync.WaitGroup
createTemplate := func(tplName string, orgID uuid.UUID) {
version := coderdtest.CreateTemplateVersion(t, ownerClient, orgID, nil)
wg.Add(1)
go func() {
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, version.ID)
wg.Done()
}()
coderdtest.CreateTemplate(t, ownerClient, orgID, version.ID, func(request *codersdk.CreateTemplateRequest) {
request.Name = tplName
})
}
for _, tplName := range args.firstTemplates {
createTemplate(tplName, first.OrganizationID)
}
for _, tplName := range args.secondTemplates {
createTemplate(tplName, second.ID)
}
wg.Wait()
return setupData{
firstResponse: first,
owner: ownerClient,
second: second,
member: member,
}
}
// Test creating a workspace in the second organization with a template
// name.
t.Run("CreateMultipleOrganization", func(t *testing.T) {
t.Parallel()
const templateName = "secondtemplate"
setup := setupMultipleOrganizations(t, setupArgs{
secondTemplates: []string{templateName},
})
member := setup.member
args := []string{
"create",
"my-workspace",
"-y",
"--template", templateName,
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, member, root)
_ = ptytest.New(t).Attach(inv)
err := inv.Run()
require.NoError(t, err)
ws, err := member.WorkspaceByOwnerAndName(context.Background(), codersdk.Me, "my-workspace", codersdk.WorkspaceOptions{})
if assert.NoError(t, err, "expected workspace to be created") {
assert.Equal(t, ws.TemplateName, templateName)
assert.Equal(t, ws.OrganizationName, setup.second.Name, "workspace in second organization")
}
})
// If a template name exists in two organizations, the workspace create will
// fail.
t.Run("AmbiguousTemplateName", func(t *testing.T) {
t.Parallel()
const templateName = "ambiguous"
setup := setupMultipleOrganizations(t, setupArgs{
firstTemplates: []string{templateName},
secondTemplates: []string{templateName},
})
member := setup.member
args := []string{
"create",
"my-workspace",
"-y",
"--template", templateName,
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, member, root)
_ = ptytest.New(t).Attach(inv)
err := inv.Run()
require.Error(t, err, "expected error due to ambiguous template name")
require.ErrorContains(t, err, "multiple templates found")
})
// Ambiguous template names are allowed if the organization is specified.
t.Run("WorkingAmbiguousTemplateName", func(t *testing.T) {
t.Parallel()
const templateName = "ambiguous"
setup := setupMultipleOrganizations(t, setupArgs{
firstTemplates: []string{templateName},
secondTemplates: []string{templateName},
})
member := setup.member
args := []string{
"create",
"my-workspace",
"-y",
"--template", templateName,
"--org", setup.second.Name,
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, member, root)
_ = ptytest.New(t).Attach(inv)
err := inv.Run()
require.NoError(t, err)
ws, err := member.WorkspaceByOwnerAndName(context.Background(), codersdk.Me, "my-workspace", codersdk.WorkspaceOptions{})
if assert.NoError(t, err, "expected workspace to be created") {
assert.Equal(t, ws.TemplateName, templateName)
assert.Equal(t, ws.OrganizationName, setup.second.Name, "workspace in second organization")
}
})
// If an organization is specified, but the template is not in that
// organization, an error is thrown.
t.Run("CreateIncorrectOrg", func(t *testing.T) {
t.Parallel()
const templateName = "secondtemplate"
setup := setupMultipleOrganizations(t, setupArgs{
firstTemplates: []string{templateName},
})
member := setup.member
args := []string{
"create",
"my-workspace",
"-y",
"--org", setup.second.Name,
"--template", templateName,
}
inv, root := clitest.New(t, args...)
clitest.SetupConfig(t, member, root)
_ = ptytest.New(t).Attach(inv)
err := inv.Run()
require.Error(t, err)
// The error message should indicate the flag to fix the issue.
require.ErrorContains(t, err, fmt.Sprintf("--org=%q", "coder"))
})
}