From a860b86256293ab11d92eae3b10994f9b06c4436 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 6 Jun 2022 14:43:16 -0500 Subject: [PATCH] fix: support substring search on workspace name (#2096) --- coderd/database/databasefake/databasefake.go | 2 +- coderd/database/queries.sql.go | 4 +-- coderd/database/queries/workspaces.sql | 4 +-- coderd/workspaces_test.go | 36 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index da3a739c32629..f4531c1ce0b60 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -330,7 +330,7 @@ func (q *fakeQuerier) GetWorkspacesWithFilter(_ context.Context, arg database.Ge if !arg.Deleted && workspace.Deleted { continue } - if arg.Name != "" && workspace.Name != arg.Name { + if arg.Name != "" && !strings.Contains(workspace.Name, arg.Name) { continue } workspaces = append(workspaces, workspace) diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 54cb5bc6a1d53..3b4c9d53ab671 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -3658,10 +3658,10 @@ WHERE owner_id = $3 ELSE true END - -- Filter by name + -- Filter by name, matching on substring AND CASE WHEN $4 :: text != '' THEN - LOWER(name) = LOWER($4) + LOWER(name) LIKE '%' || LOWER($4) || '%' ELSE true END ` diff --git a/coderd/database/queries/workspaces.sql b/coderd/database/queries/workspaces.sql index 291f04c96da7a..8c17c323b091d 100644 --- a/coderd/database/queries/workspaces.sql +++ b/coderd/database/queries/workspaces.sql @@ -28,10 +28,10 @@ WHERE owner_id = @owner_id ELSE true END - -- Filter by name + -- Filter by name, matching on substring AND CASE WHEN @name :: text != '' THEN - LOWER(name) = LOWER(@name) + LOWER(name) LIKE '%' || LOWER(@name) || '%' ELSE true END ; diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index e7fa0855e0bdf..52ecadb8d3c48 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -232,6 +232,42 @@ func TestWorkspaceByOwnerAndName(t *testing.T) { }) } +func TestWorkspaceFilter(t *testing.T) { + t.Parallel() + t.Run("Name", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + 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, user.OrganizationID, template.ID) + + // full match + ws, err := client.Workspaces(context.Background(), codersdk.WorkspaceFilter{ + Name: workspace.Name, + }) + require.NoError(t, err) + require.Len(t, ws, 1, workspace.Name) + require.Equal(t, workspace.ID, ws[0].ID) + + // partial match + ws, err = client.Workspaces(context.Background(), codersdk.WorkspaceFilter{ + Name: workspace.Name[1 : len(workspace.Name)-2], + }) + require.NoError(t, err) + require.Len(t, ws, 1) + require.Equal(t, workspace.ID, ws[0].ID) + + // no match + ws, err = client.Workspaces(context.Background(), codersdk.WorkspaceFilter{ + Name: "$$$$", + }) + require.NoError(t, err) + require.Len(t, ws, 0) + }) +} + func TestPostWorkspaceBuild(t *testing.T) { t.Parallel() t.Run("NoTemplateVersion", func(t *testing.T) {