mirror of
https://github.com/larksuite/cli.git
synced 2026-07-04 23:15:25 +08:00
262 lines
7.5 KiB
Go
262 lines
7.5 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package core
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestDetectWorkspaceFromEnv(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
env map[string]string
|
|
expect Workspace
|
|
}{
|
|
{
|
|
name: "no agent env → local",
|
|
env: map[string]string{},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=1 → openclaw",
|
|
env: map[string]string{"OPENCLAW_CLI": "1"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=true → local (strict ==1 check)",
|
|
env: map[string]string{"OPENCLAW_CLI": "true"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=yes → local",
|
|
env: map[string]string{"OPENCLAW_CLI": "yes"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=0 → local",
|
|
env: map[string]string{"OPENCLAW_CLI": "0"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI empty → local",
|
|
env: map[string]string{"OPENCLAW_CLI": ""},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=1 with trailing space → local (strict)",
|
|
env: map[string]string{"OPENCLAW_CLI": "1 "},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "generic FEISHU_APP_ID + SECRET → local (not a Hermes signal)",
|
|
env: map[string]string{"FEISHU_APP_ID": "cli_abc", "FEISHU_APP_SECRET": "xxx"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "HERMES_HOME set → hermes",
|
|
env: map[string]string{"HERMES_HOME": "/Users/me/.hermes"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "HERMES_QUIET=1 → hermes (set by gateway)",
|
|
env: map[string]string{"HERMES_QUIET": "1"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "HERMES_EXEC_ASK=1 → hermes",
|
|
env: map[string]string{"HERMES_EXEC_ASK": "1"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "HERMES_GATEWAY_TOKEN set → hermes",
|
|
env: map[string]string{"HERMES_GATEWAY_TOKEN": "69ce6b...6065"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "HERMES_SESSION_KEY set → hermes",
|
|
env: map[string]string{"HERMES_SESSION_KEY": "agent:main:feishu:dm:oc_xxx"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "HERMES_QUIET=0 alone → local (strict ==1 check)",
|
|
env: map[string]string{"HERMES_QUIET": "0"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=1 + HERMES_HOME both set → openclaw wins (priority)",
|
|
env: map[string]string{"OPENCLAW_CLI": "1", "HERMES_HOME": "/Users/me/.hermes"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "FEISHU_APP_ID + HERMES_HOME → hermes (HERMES_ signals suffice)",
|
|
env: map[string]string{"FEISHU_APP_ID": "cli_abc", "FEISHU_APP_SECRET": "xxx", "HERMES_HOME": "/Users/me/.hermes"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
{
|
|
name: "OPENCLAW_HOME set → openclaw (older OpenClaw builds without subprocess marker)",
|
|
env: map[string]string{"OPENCLAW_HOME": "/Users/me/.openclaw"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "OPENCLAW_STATE_DIR set → openclaw",
|
|
env: map[string]string{"OPENCLAW_STATE_DIR": "/srv/openclaw/state"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CONFIG_PATH set → openclaw",
|
|
env: map[string]string{"OPENCLAW_CONFIG_PATH": "/etc/openclaw/openclaw.json"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "OPENCLAW_HOME + FEISHU both set → openclaw wins (priority)",
|
|
env: map[string]string{"OPENCLAW_HOME": "/Users/me/.openclaw", "FEISHU_APP_ID": "cli_abc", "FEISHU_APP_SECRET": "xxx"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "LARKSUITE_CLI_APP_ID does not affect workspace",
|
|
env: map[string]string{"LARKSUITE_CLI_APP_ID": "cli_local", "LARKSUITE_CLI_APP_SECRET": "local_secret"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "LARK_CHANNEL=1 → lark-channel",
|
|
env: map[string]string{"LARK_CHANNEL": "1"},
|
|
expect: WorkspaceLarkChannel,
|
|
},
|
|
{
|
|
name: "LARK_CHANNEL=true → local (strict ==1 check)",
|
|
env: map[string]string{"LARK_CHANNEL": "true"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "LARK_CHANNEL=0 → local",
|
|
env: map[string]string{"LARK_CHANNEL": "0"},
|
|
expect: WorkspaceLocal,
|
|
},
|
|
{
|
|
name: "OPENCLAW_CLI=1 + LARK_CHANNEL=1 → openclaw wins (priority)",
|
|
env: map[string]string{"OPENCLAW_CLI": "1", "LARK_CHANNEL": "1"},
|
|
expect: WorkspaceOpenClaw,
|
|
},
|
|
{
|
|
name: "HERMES_HOME + LARK_CHANNEL=1 → hermes wins (priority over lark-channel)",
|
|
env: map[string]string{"HERMES_HOME": "/Users/me/.hermes", "LARK_CHANNEL": "1"},
|
|
expect: WorkspaceHermes,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
getenv := func(key string) string { return tt.env[key] }
|
|
got := DetectWorkspaceFromEnv(getenv)
|
|
if got != tt.expect {
|
|
t.Errorf("DetectWorkspaceFromEnv() = %q, want %q", got, tt.expect)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWorkspaceDisplay(t *testing.T) {
|
|
tests := []struct {
|
|
ws Workspace
|
|
expect string
|
|
}{
|
|
{WorkspaceLocal, "local"},
|
|
{Workspace(""), "local"},
|
|
{WorkspaceOpenClaw, "openclaw"},
|
|
{WorkspaceHermes, "hermes"},
|
|
{WorkspaceLarkChannel, "lark-channel"},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := tt.ws.Display(); got != tt.expect {
|
|
t.Errorf("Workspace(%q).Display() = %q, want %q", tt.ws, got, tt.expect)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWorkspaceIsLocal(t *testing.T) {
|
|
if !WorkspaceLocal.IsLocal() {
|
|
t.Error("WorkspaceLocal.IsLocal() should be true")
|
|
}
|
|
if !Workspace("").IsLocal() {
|
|
t.Error(`Workspace("").IsLocal() should be true`)
|
|
}
|
|
if WorkspaceOpenClaw.IsLocal() {
|
|
t.Error("WorkspaceOpenClaw.IsLocal() should be false")
|
|
}
|
|
}
|
|
|
|
func TestSetCurrentWorkspace(t *testing.T) {
|
|
orig := CurrentWorkspace()
|
|
defer SetCurrentWorkspace(orig)
|
|
|
|
SetCurrentWorkspace(WorkspaceOpenClaw)
|
|
if got := CurrentWorkspace(); got != WorkspaceOpenClaw {
|
|
t.Errorf("CurrentWorkspace() = %q, want %q", got, WorkspaceOpenClaw)
|
|
}
|
|
|
|
SetCurrentWorkspace(WorkspaceLocal)
|
|
if got := CurrentWorkspace(); got != WorkspaceLocal {
|
|
t.Errorf("CurrentWorkspace() = %q, want %q", got, WorkspaceLocal)
|
|
}
|
|
}
|
|
|
|
func TestGetRuntimeDir(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", tmp)
|
|
|
|
orig := CurrentWorkspace()
|
|
defer SetCurrentWorkspace(orig)
|
|
|
|
// Local → base dir (same as pre-workspace behavior)
|
|
SetCurrentWorkspace(WorkspaceLocal)
|
|
if got := GetRuntimeDir(); got != tmp {
|
|
t.Errorf("local: GetRuntimeDir() = %q, want %q", got, tmp)
|
|
}
|
|
if got := GetConfigDir(); got != tmp {
|
|
t.Errorf("local: GetConfigDir() = %q, want %q", got, tmp)
|
|
}
|
|
|
|
// OpenClaw → base/openclaw
|
|
SetCurrentWorkspace(WorkspaceOpenClaw)
|
|
want := filepath.Join(tmp, "openclaw")
|
|
if got := GetRuntimeDir(); got != want {
|
|
t.Errorf("openclaw: GetRuntimeDir() = %q, want %q", got, want)
|
|
}
|
|
|
|
// Hermes → base/hermes
|
|
SetCurrentWorkspace(WorkspaceHermes)
|
|
want = filepath.Join(tmp, "hermes")
|
|
if got := GetRuntimeDir(); got != want {
|
|
t.Errorf("hermes: GetRuntimeDir() = %q, want %q", got, want)
|
|
}
|
|
|
|
// LarkChannel → base/lark-channel
|
|
SetCurrentWorkspace(WorkspaceLarkChannel)
|
|
want = filepath.Join(tmp, "lark-channel")
|
|
if got := GetRuntimeDir(); got != want {
|
|
t.Errorf("lark-channel: GetRuntimeDir() = %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestGetConfigPath(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", tmp)
|
|
|
|
orig := CurrentWorkspace()
|
|
defer SetCurrentWorkspace(orig)
|
|
|
|
SetCurrentWorkspace(WorkspaceLocal)
|
|
want := filepath.Join(tmp, "config.json")
|
|
if got := GetConfigPath(); got != want {
|
|
t.Errorf("local: GetConfigPath() = %q, want %q", got, want)
|
|
}
|
|
|
|
SetCurrentWorkspace(WorkspaceOpenClaw)
|
|
want = filepath.Join(tmp, "openclaw", "config.json")
|
|
if got := GetConfigPath(); got != want {
|
|
t.Errorf("openclaw: GetConfigPath() = %q, want %q", got, want)
|
|
}
|
|
}
|