From dea5e9491a7de4883db03329658d3b7b7cf7dba9 Mon Sep 17 00:00:00 2001 From: hongming-codex-laptop Date: Thu, 14 May 2026 07:40:04 -0700 Subject: [PATCH] fix(handlers): repair instructions test compile --- .../internal/handlers/handlers_test.go | 5 +++++ .../internal/handlers/instructions_test.go | 11 ++++------ .../handlers/org_helpers_security_test.go | 2 +- .../handlers/plugins_install_eic_test.go | 5 +++++ .../internal/handlers/plugins_test.go | 21 +++++++++++-------- .../internal/handlers/terminal_test.go | 19 +++++++++++++++-- .../handlers/workspace_provision_test.go | 14 +++++++++++++ 7 files changed, 58 insertions(+), 19 deletions(-) diff --git a/workspace-server/internal/handlers/handlers_test.go b/workspace-server/internal/handlers/handlers_test.go index ee37b70d..c0684d96 100644 --- a/workspace-server/internal/handlers/handlers_test.go +++ b/workspace-server/internal/handlers/handlers_test.go @@ -361,6 +361,11 @@ func TestWorkspaceCreate(t *testing.T) { } func TestBuildProvisionerConfig_IncludesAwarenessSettings(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectQuery(`SELECT digest FROM runtime_image_pins`). + WithArgs("claude-code"). + WillReturnError(sql.ErrNoRows) + broadcaster := newTestBroadcaster() handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", "/tmp/configs") diff --git a/workspace-server/internal/handlers/instructions_test.go b/workspace-server/internal/handlers/instructions_test.go index f8b75ced..6c79bffe 100644 --- a/workspace-server/internal/handlers/instructions_test.go +++ b/workspace-server/internal/handlers/instructions_test.go @@ -11,7 +11,6 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/Molecule-AI/molecule-monorepo/platform/internal/db" "github.com/gin-gonic/gin" ) @@ -193,7 +192,7 @@ func TestInstructionsHandler_Create_InvalidScope(t *testing.T) { handler.Create(c) - if w.Code != http.BadRequest { + if w.Code != http.StatusBadRequest { t.Fatalf("expected 400, got %d: %s", w.Code, w.Body.String()) } } @@ -277,7 +276,7 @@ func TestInstructionsHandler_Create_WorkspaceScopeWithScopeTarget(t *testing.T) "scope_target": wsID, "title": "WS rule", "content": "Use HTTPS", - "priority": 10, + "priority": 10, }) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) @@ -299,10 +298,9 @@ func TestInstructionsHandler_Create_WorkspaceScopeWithScopeTarget(t *testing.T) func TestInstructionsHandler_Update_Success(t *testing.T) { mock := setupTestDB(t) handler := NewInstructionsHandler() - title := "Updated title" mock.ExpectExec(regexp.QuoteMeta("UPDATE platform_instructions SET\n\t\t\t\ttitle = COALESCE($2, title),\n\t\t\t\tcontent = COALESCE($3, content),\n\t\t\t\tpriority = COALESCE($4, priority),\n\t\t\t\tenabled = COALESCE($5, enabled),\n\t\t\t\tupdated_at = NOW()\n\t\t\t\tWHERE id = $1")). - WithArgs(&title, "inst-1"). + WithArgs("inst-1", sqlmock.AnyArg(), nil, nil, nil). WillReturnResult(sqlmock.NewResult(0, 1)) body, _ := json.Marshal(map[string]interface{}{"title": "Updated title"}) @@ -325,10 +323,9 @@ func TestInstructionsHandler_Update_Success(t *testing.T) { func TestInstructionsHandler_Update_NotFound(t *testing.T) { mock := setupTestDB(t) handler := NewInstructionsHandler() - title := "Updated title" mock.ExpectExec(regexp.QuoteMeta("UPDATE platform_instructions SET\n\t\t\t\ttitle = COALESCE($2, title),\n\t\t\t\tcontent = COALESCE($3, content),\n\t\t\t\tpriority = COALESCE($4, priority),\n\t\t\t\tenabled = COALESCE($5, enabled),\n\t\t\t\tupdated_at = NOW()\n\t\t\t\tWHERE id = $1")). - WithArgs(&title, "nonexistent"). + WithArgs("nonexistent", sqlmock.AnyArg(), nil, nil, nil). WillReturnResult(sqlmock.NewResult(0, 0)) body, _ := json.Marshal(map[string]interface{}{"title": "Updated title"}) diff --git a/workspace-server/internal/handlers/org_helpers_security_test.go b/workspace-server/internal/handlers/org_helpers_security_test.go index 2adbc22f..6ae2e879 100644 --- a/workspace-server/internal/handlers/org_helpers_security_test.go +++ b/workspace-server/internal/handlers/org_helpers_security_test.go @@ -93,7 +93,7 @@ func TestResolveInsideRoot_DotPathComponent(t *testing.T) { if err != nil { t.Fatalf("dot path component: unexpected error: %v", err) } - if got[len(got)-14:] != "/subdir/file.txt" { + if !strings.HasSuffix(got, "/subdir/file.txt") { t.Errorf("dot path component: got %q, want suffix /subdir/file.txt", got) } } diff --git a/workspace-server/internal/handlers/plugins_install_eic_test.go b/workspace-server/internal/handlers/plugins_install_eic_test.go index 2150728b..17ec1651 100644 --- a/workspace-server/internal/handlers/plugins_install_eic_test.go +++ b/workspace-server/internal/handlers/plugins_install_eic_test.go @@ -342,6 +342,11 @@ func TestPluginInstall_InstanceLookupError_Returns503(t *testing.T) { // ---------- dispatch: uninstall ---------- func TestPluginUninstall_SaaS_DispatchesToEIC(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectExec("DELETE FROM workspace_plugins WHERE workspace_id"). + WithArgs("ws-1", "browser-automation"). + WillReturnResult(sqlmock.NewResult(0, 1)) + stubReadPluginManifestViaEIC(t, func(ctx context.Context, instanceID, runtime, pluginName string) ([]byte, error) { return []byte("name: browser-automation\nskills:\n - browse\n"), nil }) diff --git a/workspace-server/internal/handlers/plugins_test.go b/workspace-server/internal/handlers/plugins_test.go index 6d56602f..b3a0cdbf 100644 --- a/workspace-server/internal/handlers/plugins_test.go +++ b/workspace-server/internal/handlers/plugins_test.go @@ -629,6 +629,9 @@ func TestPluginInstall_RejectsUnknownScheme(t *testing.T) { } func TestPluginInstall_LocalSourceReachesContainerLookup(t *testing.T) { + mock := setupTestDB(t) + expectAllowlistAllowAll(mock) + base := t.TempDir() pluginDir := filepath.Join(base, "demo") _ = os.MkdirAll(pluginDir, 0o755) @@ -955,14 +958,14 @@ func TestLogInstallLimitsOnce(t *testing.T) { func TestRegexpEscapeForAwk(t *testing.T) { cases := map[string]string{ - "my-plugin": `my-plugin`, - "# Plugin: foo /": `# Plugin: foo \/`, - "# Plugin: a.b /": `# Plugin: a\.b \/`, - "foo[bar]": `foo\[bar\]`, - "a*b+c?": `a\*b\+c\?`, - "path|with|pipes": `path\|with\|pipes`, - `back\slash`: `back\\slash`, - "": ``, + "my-plugin": `my-plugin`, + "# Plugin: foo /": `# Plugin: foo \/`, + "# Plugin: a.b /": `# Plugin: a\.b \/`, + "foo[bar]": `foo\[bar\]`, + "a*b+c?": `a\*b\+c\?`, + "path|with|pipes": `path\|with\|pipes`, + `back\slash`: `back\\slash`, + "": ``, } for in, want := range cases { got := regexpEscapeForAwk(in) @@ -1247,7 +1250,7 @@ func TestPluginDownload_GithubSchemeStreamsTarball(t *testing.T) { scheme: "github", fetchFn: func(_ context.Context, _ string, dst string) (string, error) { files := map[string]string{ - "plugin.yaml": "name: remote-plugin\nversion: 1.0.0\n", + "plugin.yaml": "name: remote-plugin\nversion: 1.0.0\n", "skills/x/SKILL.md": "---\nname: x\n---\n", "adapters/claude_code.py": "from plugins_registry.builtins import AgentskillsAdaptor as Adaptor\n", } diff --git a/workspace-server/internal/handlers/terminal_test.go b/workspace-server/internal/handlers/terminal_test.go index 34bc76d3..5e10c97d 100644 --- a/workspace-server/internal/handlers/terminal_test.go +++ b/workspace-server/internal/handlers/terminal_test.go @@ -340,6 +340,11 @@ func TestSSHCommandCmd_BuildsArgv(t *testing.T) { // a workspace must still be able to access its own terminal. The CanCommunicate // fast-path returns true when callerID == targetID. func TestTerminalConnect_KI005_AllowsOwnTerminal(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectQuery("SELECT COALESCE"). + WithArgs("ws-alice"). + WillReturnRows(sqlmock.NewRows([]string{"instance_id"}).AddRow("")) + // CanCommunicate fast-path: callerID == targetID → returns true without DB. prev := canCommunicateCheck canCommunicateCheck = func(callerID, targetID string) bool { return callerID == targetID } @@ -367,6 +372,11 @@ func TestTerminalConnect_KI005_AllowsOwnTerminal(t *testing.T) { // skip the CanCommunicate check entirely and fall through to the Docker auth path. // We assert they get the nil-docker 503 instead of 403. func TestTerminalConnect_KI005_SkipsCheckWithoutHeader(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectQuery("SELECT COALESCE"). + WithArgs("ws-any"). + WillReturnRows(sqlmock.NewRows([]string{"instance_id"}).AddRow("")) + h := NewTerminalHandler(nil) // nil docker → 503 if reached w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) @@ -439,6 +449,9 @@ func TestTerminalConnect_KI005_AllowsSiblingWorkspace(t *testing.T) { mock.ExpectExec(`UPDATE workspace_auth_tokens SET last_used_at`). WithArgs(sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(0, 1)) + mock.ExpectQuery("SELECT COALESCE"). + WithArgs("ws-dev"). + WillReturnRows(sqlmock.NewRows([]string{"instance_id"}).AddRow("")) h := NewTerminalHandler(nil) w := httptest.NewRecorder() @@ -463,7 +476,10 @@ func TestTerminalConnect_KI005_AllowsSiblingWorkspace(t *testing.T) { // introduced in GH#1885: internal routing uses org tokens which are not in // workspace_auth_tokens, so ValidateToken would always fail for them. func TestKI005_OrgToken_SkipsValidateToken(t *testing.T) { - setupTestDB(t) // no ValidateToken ExpectQuery — none should fire + mock := setupTestDB(t) // no ValidateToken ExpectQuery — none should fire + mock.ExpectQuery("SELECT COALESCE"). + WithArgs("ws-target"). + WillReturnRows(sqlmock.NewRows([]string{"instance_id"}).AddRow("")) prev := canCommunicateCheck canCommunicateCheck = func(callerID, targetID string) bool { // Simulate platform agent → target workspace (same org). @@ -544,4 +560,3 @@ func TestSSHCommandCmd_ConnectTimeoutPresent(t *testing.T) { args) } } - diff --git a/workspace-server/internal/handlers/workspace_provision_test.go b/workspace-server/internal/handlers/workspace_provision_test.go index 9c4f56cc..7909aa7b 100644 --- a/workspace-server/internal/handlers/workspace_provision_test.go +++ b/workspace-server/internal/handlers/workspace_provision_test.go @@ -2,6 +2,7 @@ package handlers import ( "context" + "database/sql" "fmt" "net/http" "os" @@ -634,6 +635,11 @@ func TestSeedInitialMemories_EmptyMemoriesNil(t *testing.T) { // ==================== buildProvisionerConfig ==================== func TestBuildProvisionerConfig_BasicFields(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectQuery(`SELECT COALESCE\(workspace_dir`). + WithArgs("ws-basic"). + WillReturnRows(sqlmock.NewRows([]string{"workspace_dir", "workspace_access"}).AddRow("", "none")) + broadcaster := newTestBroadcaster() tmpDir := t.TempDir() handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", tmpDir) @@ -678,6 +684,14 @@ func TestBuildProvisionerConfig_BasicFields(t *testing.T) { } func TestBuildProvisionerConfig_WorkspacePathFromEnv(t *testing.T) { + mock := setupTestDB(t) + mock.ExpectQuery(`SELECT COALESCE\(workspace_dir`). + WithArgs("ws-env"). + WillReturnError(sql.ErrNoRows) + mock.ExpectQuery(`SELECT digest FROM runtime_image_pins`). + WithArgs("claude-code"). + WillReturnError(sql.ErrNoRows) + broadcaster := newTestBroadcaster() handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", t.TempDir())