coder/coderd/workspaceapps/request_test.go

292 lines
7.2 KiB
Go

package workspaceapps_test
import (
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/workspaceapps"
)
func Test_RequestValidate(t *testing.T) {
t.Parallel()
cases := []struct {
name string
req workspaceapps.Request
noNormalize bool
errContains string
}{
{
name: "OK1",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
},
{
name: "OK2",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodSubdomain,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceAndAgent: "bar.baz",
AppSlugOrPort: "qux",
},
},
{
name: "OK3",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
AgentNameOrID: uuid.New().String(),
},
},
{
name: "OK4",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AppSlugOrPort: "baz",
},
},
{
name: "OK5",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodSubdomain,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AppSlugOrPort: "8080",
},
},
{
name: "OK6",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodSubdomain,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AppSlugOrPort: "8080s",
},
},
{
name: "NoAccessMethod",
req: workspaceapps.Request{
AccessMethod: "",
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "invalid access method",
},
{
name: "UnknownAccessMethod",
req: workspaceapps.Request{
AccessMethod: "dean was here",
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "invalid access method",
},
{
name: "NoBasePath",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
noNormalize: true,
errContains: "base path is required",
},
{
name: "NoUsernameOrID",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "username or ID is required",
},
{
name: "NoMe",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "me",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: `username cannot be "me"`,
},
{
name: "InvalidWorkspaceAndAgent/EmptyWorkspace",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceAndAgent: ".bar",
AppSlugOrPort: "baz",
},
errContains: "workspace name or ID is required",
},
{
name: "NoWorkspaceNameOrID",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "workspace name or ID is required",
},
{
name: "NoAppSlugOrPort",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "",
},
errContains: "app slug or port is required",
},
{
name: "Prefix/OK",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodSubdomain,
Prefix: "blah---",
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
},
{
name: "Prefix/Invalid",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodSubdomain,
Prefix: "blah", // no trailing ---
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "prefix must have a trailing '---'",
},
{
name: "Prefix/NotAllowedPath",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodPath,
Prefix: "blah---",
BasePath: "/",
UsernameOrID: "foo",
WorkspaceNameOrID: "bar",
AgentNameOrID: "baz",
AppSlugOrPort: "qux",
},
errContains: "prefix is only valid for subdomain apps",
},
{
name: "Terminal/OtherFields/UsernameOrID",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
UsernameOrID: "foo",
AgentNameOrID: uuid.New().String(),
},
errContains: "cannot specify any fields other than",
},
{
name: "Terminal/OtherFields/WorkspaceAndAgent",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
WorkspaceAndAgent: "bar.baz",
AgentNameOrID: uuid.New().String(),
},
errContains: "cannot specify any fields other than",
},
{
name: "Terminal/OtherFields/WorkspaceNameOrID",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
WorkspaceNameOrID: "bar",
AgentNameOrID: uuid.New().String(),
},
errContains: "cannot specify any fields other than",
},
{
name: "Terminal/OtherFields/AppSlugOrPort",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
AgentNameOrID: uuid.New().String(),
AppSlugOrPort: "baz",
},
errContains: "cannot specify any fields other than",
},
{
name: "Terminal/AgentNameOrID/Empty",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
AgentNameOrID: "",
},
errContains: "agent name or ID is required",
},
{
name: "Terminal/AgentNameOrID/NotUUID",
req: workspaceapps.Request{
AccessMethod: workspaceapps.AccessMethodTerminal,
BasePath: "/",
AgentNameOrID: "baz",
},
errContains: `invalid agent name or ID "baz", must be a UUID`,
},
}
for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
req := c.req
if !c.noNormalize {
req = c.req.Normalize()
}
err := req.Validate()
if c.errContains == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.ErrorContains(t, err, c.errContains)
}
})
}
}